8.4 Fit-Anchor¶
Fit-Anchor is one of the most important modules in PnPInk. It is the placement engine that lets you position objects relative to placeholders without manual coordinates and without hardcoding object/template sizes.
In practice, Fit-Anchor lets you place one or many objects on a placeholder and then size, align, shift and clip them relative to that placeholder.
Fit-Anchor is about the relationship between an object and its placeholder. For visual changes applied to the object itself after placement, use Transform.
8.4.1 Dataset Mental Model¶
Fit-Anchor is easier to understand if you keep this model in mind:
- the dataset header points to a placeholder object in the SVG,
- each row cell provides one or many source objects,
- Fit-Anchor defines how those source objects are positioned relative to that placeholder for each generated card/instance.
8.4.2 Fit vs Transform¶
Use:
Fit/Fit-Anchorfor placement relative to the placeholderTransformfor changes applied to the placed object itself
Typical Fit-Anchor concerns are:
- size inside the placeholder
- alignment within the placeholder
- border or fit area
- clipping to the placeholder
Typical Transform concerns are:
- rotate
- mirror
- opacity
- soft edges
- later, other visual effects applied directly to the object
8.4.3 What Is an "Object" Here?¶
In this documentation, we call IDs "objects" (not "elements") from the DSL/user point of view.
An object can be:
- an existing SVG object by ID (rect, path, group, text, image, etc.),
- a dynamic object created by
Source(local file, spritesheet frame, internet URL, Wikimedia/Pixabay, icon library), - a multivalue object list in one cell:
id1~7 id2~9 id3~3, - an explicit object array:
[id1 id2 id3](optionally with local array layout).
Representative examples of dataset cells:
8.4.4 Syntax and Style¶
Fit-Anchor follows the same DSL conventions as other modules:
Module{ key1=value1 key2=value2 ... }long form.- The module name can be abbreviated as
F. - Every Fit-Anchor parameter has a first-letter alias:
mode/m,anchor/a,border/b,shift/s, andclip/c. - Mode values can omit the parameter name, for example
.F{inside}or.F{i}. - Compact shorthand with
~is available for the most common Fit-Anchor operations.
Long form:
object_id.Fit{mode=inside anchor=7 border=[-2] shift=[1 0] clip}
object_id.F{m=i a=7 b=[-2] s=[1 0] c}
Fit{...} and F{...} are exactly equivalent. Parameter initials are also exactly equivalent to their full names.
| Parameter | Initial | Purpose |
|---|---|---|
mode |
m |
Scaling behavior. |
anchor |
a |
Alignment point from 1 to 9. |
border |
b |
Adjustment of the area used for scaling. |
shift |
s |
Final positional offset. |
clip |
c |
Clip overflowing content. |
Do not use f for mode. F abbreviates the module name; m abbreviates the mode parameter.
Compact form:
object_id~...
See Compact Notation (Fit-Anchor and Transform) for a visual quick-reference covering token order, defaults, optional parts, and combined examples.
Compact Example (Explained)¶
Example:
| id1~[10%]i7[-50% 0]!^^ |
Read it left to right:
[10%]-> border (resize context around placeholder),i-> modeinside,7-> anchor top-left,[-50% 0]-> shift left by half placeholder width,!-> clip to the placeholder shape,^^-> Transform rotate 180 deg.
This compact style is very expressive once you know the token order.
8.4.5 Fit-Anchor Parameters¶
The following subsections describe each Fit-Anchor parameter and what it changes in final placement. Order matters conceptually.
Mode (mode= / m=)¶
Mode defines scaling behavior relative to the usable area. If omitted, inside is used.
Equivalent examples:
| object_id.Fit{mode=inside} |
| object_id.F{m=i} |
| object_id.F{inside} |
| object_id.F{i} |
| object_id~i |
m has two related but unambiguous uses inside the block:
m=valueis the initial form of themodeparameter:.F{m=inside}or.F{m=i}.- a bare
mis the mode code formax/cover:.F{m}.
The same rule applies to the mode codes a and b: a bare .F{a} or .F{b} selects a mode, while .F{a=7} and .F{b=[-2]} set the anchor and border parameters.
Mode Reference¶
| Code | Name | Description |
|---|---|---|
i |
inside / contain | Scales proportionally to fit entirely within the area (default). |
o |
original / none | Keeps original size. |
w |
width-fit | Scales proportionally to match area width. |
h |
height-fit | Scales proportionally to match area height. |
m |
max / cover | Scales proportionally until it completely covers the area, possibly overflowing. |
x |
x-stretch | Stretches width to match the area (non-proportional). |
y |
y-stretch | Stretches height to match the area (non-proportional). |
a |
all-stretch | Scales independently in X/Y to fill the area exactly. |
The parser also reserves t (tile) and b / ? (best-fit / auto-fit), but these modes do not yet implement special scaling. Do not use them in production datasets yet.
c is not a mode code. It is the initial of the clip parameter.
Border (border= / b=)¶
Border changes the usable area on which mode computes scale.
- positive values expand,
- negative values shrink.
Important behavior:
bordermodifies placeholder size only for mode scaling.anchor,shift, andclipstill use the original placeholder as geometric reference.
In other words:
- border adjusts the fit area,
- mode computes object scale in that adjusted area,
- anchor/shift/clip are evaluated against the original placeholder.
Although mode is documented first because it is the primary choice, the placement engine computes the border-adjusted usable area before applying that mode.
Examples:
border=[-2]
border=[2 3]
border=[2 3 4 5]
object_id~[-2]i
Percent and absolute-size forms are supported:
border=[50%]
border=[125%]
border=[40x60]
border=[50%x20]
border=[23x?]
border=[?x12]
Negative WxH components can flip orientation:
border=[100%x-100%]
border=[-100%x100%]
Anchor (anchor= / a=)¶
Anchor selects the reference point used to align an object to the placeholder. Think of it as: "which point of the object goes to which point of the placeholder."
Anchor uses the original placeholder (not the border-adjusted fit area).
This makes anchor behavior stable and predictable while border only affects scale.
anchor = 1..9 follows numeric keypad:
7 8 9
4 5 6
1 2 3
Examples:
| object_id.Fit{anchor=7} |
| object_id~7 |

If no explicit anchor is provided, center (5) is used as default.
Shift (shift= / s=)¶
Shift offsets final position after anchor/fit.
object_id.Fit{anchor=7 shift=[-100% -100%]}
object_id~i8[0 %]
object_id~i8[-50% 0]
Notes:
%is relative to placeholder size,%means100%,-%means-100%,- mixed expressions are valid (
shift=[25%+2 0]). - shift uses the original placeholder frame as reference.
Clip (clip / c / !)¶
Clips outside the original placeholder shape.
In module form, clip and c are equivalent boolean flags:
object_id.Fit{mode=max clip}
object_id.F{m=m c}
object_id~!i8[0 %] # pre-clip, then fit and shift
object_id~i8[0 %]! # fit and shift, then post-clip
Position of ! matters.
8.4.6 Priority and Overrides¶
When multiple Fit-Anchor layers apply, use this precedence:
- Header defaults/global ops
- Iterator/global ops
- Item-local ops
Later layers override earlier ones for conflicting properties.
Example:
| main_art-8=~[10x10] |
|---|
| *[:fig(g918)~^^ :fig(g1720) :fig(g1264) :fig(g13590)]~[0%]5 |
Effective merge:
- start from header border,
- apply iterator-level defaults,
- apply item-level overrides last.
8.4.7 Forcing a Group BBox¶
If Inkex measures a group incorrectly, especially when it contains text, add a direct child <rect> whose SVG id or Inkscape label starts with force_bbox, force-bbox, or forcebbox. The prefix is case-insensitive. PnPInk uses that rectangle as the group's bbox, even when the rectangle is fully transparent.
data-bbox still has higher priority. Only direct child rectangles are inspected, so ordinary groups keep their normal bbox behavior.
heart_iconinsidemain_art-placeholdersp1, scaled to cover the placeholder and centerednodeX, and place it inside the placeholder