transform-box
Defining the layout box to which transform and transform-origin properties relate.
Overview
| Class | Declarations |
|---|---|
transform-content | transform-box: content-box;
|
transform-border | transform-box: border-box;
|
transform-fill | transform-box: fill-box;
|
transform-stroke | transform-box: stroke-box;
|
transform-view | transform-box: view-box;
|
transform-box:<box> | transform-box: <box>;
|
Examples
Choose the transform reference box
Each SVG rectangle translates by 50% of a different reference width. Its fill is 64 units wide, its 16-unit stroke expands the width to 80, and the SVG viewBox is 240 units wide.
<!-- Fill box · translate 32 units --><svg width="240" height="160" viewBox="0 0 240 160" role="img" aria-label="Rectangle translated from its dashed source bounds" class="block h:auto max-w:100% outline:1px|solid|var(--color-line-muted)"> <rect x="24" y="60" width="64" height="40" fill="none" stroke="#7c3aed" stroke-dasharray="4 4" /> <rect id="target" x="24" y="60" width="64" height="40" class="fill-blue-20 stroke-blue-60 transform:translateX(50%) transform-fill stroke-width:16px" /></svg><!-- Stroke box · translate 40 units --><svg width="240" height="160" viewBox="0 0 240 160" role="img" aria-label="Rectangle translated from its dashed source bounds" class="block h:auto max-w:100% outline:1px|solid|var(--color-line-muted)"> <rect x="24" y="60" width="64" height="40" fill="none" stroke="#7c3aed" stroke-dasharray="4 4" /> <rect id="target" x="24" y="60" width="64" height="40" class="fill-blue-20 stroke-blue-60 transform:translateX(50%) transform-stroke stroke-width:16px" /></svg><!-- View box · translate 120 units --><svg width="240" height="160" viewBox="0 0 240 160" role="img" aria-label="Rectangle translated from its dashed source bounds" class="block h:auto max-w:100% outline:1px|solid|var(--color-line-muted)"> <rect x="24" y="60" width="64" height="40" fill="none" stroke="#7c3aed" stroke-dasharray="4 4" /> <rect id="target" x="24" y="60" width="64" height="40" class="fill-blue-20 stroke-blue-60 transform:translateX(50%) transform-view stroke-width:16px" /></svg>Generated CSS
@layer utilities { .transform-fill { transform-box: fill-box } .transform-stroke { transform-box: stroke-box } .transform-view { transform-box: view-box }}The violet dashed rectangle preserves the source coordinates. The class selects the reference box without resizing the underlying SVG geometry. The outer outline marks the SVG viewport.
Use the border box for HTML elements
A 50% translation is 80px for this 160px border box. Compare its 108px content box, which excludes the authored border and asymmetric padding.
<!-- Border box · translate 80px --><div class="w-3xs max-w:100% py-lg"> <div class="h:100px w:160px outline:1px|dashed|var(--color-line-muted)"> <div id="target" class="h:100px w:160px pb-lg pl-xl pr-sm pt-sm b:4px|solid|var(--color-blue-60) font-sm bg-blue-10 fg-blue-80 transform:translateX(50%) box-border transform-border"> Reference box </div> </div></div><!-- Content box · translate 54px --><div class="w-3xs max-w:100% py-lg"> <div class="h:100px w:160px outline:1px|dashed|var(--color-line-muted)"> <div id="target" class="h:100px w:160px pb-lg pl-xl pr-sm pt-sm b:4px|solid|var(--color-blue-60) font-sm bg-blue-10 fg-blue-80 transform:translateX(50%) box-border transform-content"> Reference box </div> </div></div>Both elements keep the same 160 × 100 layout dimensions. The reference changes percentage transform calculations. For HTML boxes, fill-box resolves to the content box; stroke-box and view-box resolve to the border box.
Pair with transform origin
Keep the SVG fill box and 1.5 scale fixed, then compare center and top-left origins. The original 24-unit circle remains visible as a dashed guide.
<!-- Fill center · center remains at 72, 80 --><svg width="240" height="160" viewBox="0 0 240 160" role="img" aria-label="Circle scaled relative to its original dashed outline" class="block h:auto max-w:100% outline:1px|solid|var(--color-line-muted)"> <circle id="target" cx="72" cy="80" r="24" class="fill-blue-20 stroke-blue-60 transform:scale(1.5) transform-fill stroke-width:2px transform-origin:center" /> <circle aria-hidden="true" cx="72" cy="80" r="24" fill="none" stroke="#7c3aed" stroke-dasharray="4 4" class="untouchable" /></svg><!-- Fill top left · center moves to 84, 92 --><svg width="240" height="160" viewBox="0 0 240 160" role="img" aria-label="Circle scaled relative to its original dashed outline" class="block h:auto max-w:100% outline:1px|solid|var(--color-line-muted)"> <circle id="target" cx="72" cy="80" r="24" class="fill-blue-20 stroke-blue-60 transform:scale(1.5) transform-fill stroke-width:2px transform-origin:top|left" /> <circle aria-hidden="true" cx="72" cy="80" r="24" fill="none" stroke="#7c3aed" stroke-dasharray="4 4" class="untouchable" /></svg>The reference box defines the coordinate region; transform-origin locates the pivot in that region. A scale around a corner shifts the circle’s center even though its source coordinates remain unchanged.
Apply conditionally
Widen to sm to switch the SVG from its fill box to its view box. The same 50% translation then uses the full SVG width. Print returns to the fill box.
<!-- Fill → view box at sm --><svg width="240" height="160" viewBox="0 0 240 160" role="img" aria-label="Rectangle translated from its dashed source bounds" class="block h:auto max-w:100% outline:1px|solid|var(--color-line-muted)"> <rect x="24" y="60" width="64" height="40" fill="none" stroke="#7c3aed" stroke-dasharray="4 4" /> <rect id="target" x="24" y="60" width="64" height="40" class="fill-blue-20 stroke-blue-60 transform:translateX(50%) transform-fill stroke-width:16px transform-fill@print transform-view@screen@sm" /></svg>This is a native SVG reference-box change. Its effect comes from different reference widths, not from replacing the shape or changing its coordinates.