An inline SVG sizes itself from its viewBox unless both axes are definite
Fact
An <svg> is a replaced element, and a viewBox gives it an intrinsic aspect ratio. Layout keeps consulting that ratio wherever the CSS leaves either axis open, and the ratio wins over the box the surrounding rules seem to describe.
Two places this bites:
- A
1frtrack isminmax(auto, 1fr). The auto minimum is the item's min-content size, which the SVG derives from its ratio, so a grid of square cells silently stretches to the tallest bottle-shaped child. - A centred grid item sits in an
autorow.display:grid; place-items:centeron a box with an explicit height still creates an implicit row sized by its content, so a child'sheight:100%has no definite basis and the ratio decides. The parent's height looks definite and is not the one being resolved against. - Insets do not size a replaced element. With
position:absolute, all four offsets set andwidth/heightauto, the width comes fromleft/right, the height comes from the ratio, andbottomis simply ignored — the element overflows its own inset box.
Why it matters
The overflow is painted under whatever comes later in the DOM, so the symptom is not "this element is too big" but "the row below is covering mine" — a z-order-looking bug in a layout that is actually mis-sized. It also scales with content: one oddly-proportioned icon widens every track in the grid.
How to apply
- Write grid tracks as
repeat(n, minmax(0, 1fr))whenever a cell holds anything with an intrinsic ratio. - Prefer a plain block parent with a definite height over centring tricks, or write the track out:
grid-template-rows: minmax(0, 1fr). - Give the SVG a definite box on both axes rather than trusting insets:
width:calc(100% - 6px); height:calc(100% - 14px), or wrap it in a non-replaced element that the insets can size and let the SVG fill that. preserveAspectRatio(defaultxMidYMid meet) then letterboxes the drawing inside whatever box you gave it, which is usually the intent anyway.