CSS transform-box Property
The transform-box property defines the layout box or reference box that the transform and transform-origin properties relate to.
| content-box | Uses the content box as the reference box for transformations. |
| border-box | Uses the border box as the reference box for transformations. |
| fill-box | Uses the object bounding box as the reference box, typically used for SVG elements. |
| stroke-box | Uses the stroke bounding box as the reference box for SVG elements. |
| view-box | Uses the nearest SVG viewport as the reference box for transformations. |
Code Examples
A basic example showing an HTML box rotating 45 degrees relative to its own border-box boundaries.
<style>
.container {
width: 200px;
height: 200px;
border: 2px solid #333333;
display: flex;
align-items: center;
justify-content: center;
}
.box {
width: 100px;
height: 100px;
background-color: #ff5733;
transform-box: border-box;
transform-origin: center;
transform: rotate(45deg);
}
</style>
<div class="container">
<div class="box"></div>
</div>An advanced example using fill-box to ensure an SVG rectangle rotates around its own center, toggled via JavaScript.
<style>
svg {
background-color: #f0f0f0;
border: 1px solid #cccccc;
}
.gear {
fill: #007bff;
transform-origin: center;
transition: transform 1s;
}
.spin-mode {
transform-box: fill-box;
transform: rotate(360deg);
}
</style>
<svg width="200" height="200" viewBox="0 0 200 200">
<rect id="targetRect" class="gear" x="75" y="75" width="50" height="50" />
</svg>
<button id="trigger">Toggle Spin</button>
<script>
const btn = document.getElementById("trigger");
const rect = document.getElementById("targetRect");
btn.addEventListener("click", () => {
rect.classList.toggle("spin-mode");
if(rect.classList.contains("spin-mode")) {
rect.style.fill = "#28a745";
} else {
rect.style.fill = "#007bff";
}
});
</script>Pro Tip
If you are struggling to center-rotate an SVG element and it keeps swinging around like a pendulum, set transform-box to fill-box and transform-origin to center. This combo is the silver bullet for making SVG shapes behave like standard CSS blocks.
Deep Dive
Think of the transform-box as the boundary line of a sports field. If you tell a player to run to the center, they need to know if you mean the center of the whole stadium or just the active playing turf. In CSS, when you rotate or scale an element, the browser needs to know which box it is measuring from. For standard HTML elements, this defaults to the border-box. However, SVG elements traditionally use the entire SVG canvas (view-box) as their reference. By changing this property to fill-box, you tell the browser to ignore the giant canvas and focus only on the specific shape's dimensions. This is critical for getting individual SVG icons or shapes to spin around their own center points rather than the top-left corner of the parent SVG container.
Best Practices
Use fill-box when you are working with SVG shapes that need to rotate or scale relative to their own geometry. For standard HTML layout elements, the default border-box is usually what you want. Always pair this property with a clear transform-origin to ensure your animations are predictable across different browsers.
Common Pitfalls
A common mistake is trying to use fill-box on a standard HTML div and expecting it to behave differently than border-box. It won't. This property shines mostly in the SVG world where the coordinate systems can be confusing. Also, keep in mind that IE11 and some older mobile browsers do not support this, which can result in your SVGs flying off the screen during an animation if they fall back to the view-box default.
Accessibility
Ensure that any transformations applied do not move interactive elements, like buttons or links, outside of the visible area or cause them to overlap and obscure text. While transform-box itself does not directly impact screen readers, the visual movement it controls should not be so rapid or flashing that it triggers photosensitivity issues.
Dev Data Table: transform-box property
| default | view-box |
| animatable | no |
| inherited | no |
| experimental | no |
| year_intro | 2015 |
| year_standard | 2018 |
| js_syntax_1 | element.style.transformBox = "fill-box"; |
| js_syntax_2 | element.style.setProperty("transform-box", "fill-box"); |
| js_note | When manipulating this property via JavaScript, remember that it specifically alters how the transform-origin is calculated for the element. |
| browsers | { "Chrome": 64, "Edge": 79, "Firefox": 55, "Safari": 11, "Opera": 51, "Chrome Android": 64, "Safari on iOS": 11, "Samsung Internet": 9, "Opera Mobile": 47 } |