Web Platform · CSS Layout
Intrinsic Sizing and Aspect Ratio
What min-content, max-content and fit-content mean numerically, how replaced elements report their natural size, and how aspect-ratio transfers a definite dimension across axes.
A box whose width is auto still needs a width. When the layout algorithm has no definite size from the containing block, it asks the content how large it would like to be, and the answer comes from intrinsic sizing: a set of measurements derived from the content itself. These measurements are not one number but several, and different layout modes consume different ones.
Intrinsic sizing is where text wrapping, image dimensions, table columns, flex items and grid tracks meet. It is also where aspect-ratio does its work, since the property functions by contributing to the intrinsic sizes of a box rather than by acting as a post-layout correction.
Three measurements, not one
The two extreme measurements are straightforward. The max-content size is the inline size the content would take if it were laid out on one line with no forced breaks: the sum of all unbreakable runs plus the spaces between them. The min-content size is the inline size required by the widest unbreakable unit, which for text is the longest word, for an image its natural width, and for a nested box its own min-content size.
The fit-content size is a function of the available space. A box sized to fit-content takes its max-content size when that fits in the available space, its min-content size when even that does not fit, and the available space in between. Formally, fit-content(limit) evaluates to the smaller of the max-content size and the larger of the min-content size and the limit. The keyword fit-content, without an argument, behaves as fit-content(stretch): the shrink-to-fit behaviour that floats and absolutely positioned boxes get implicitly from width: auto.
The shrink-to-fit formula used by floats and absolutely positioned boxes with width: auto is the older form of the same idea: min(max(preferred minimum, available), preferred), where the preferred minimum is min-content and the preferred is max-content. This is why a float containing short text is only as wide as that text laid out on one line, and why a float that runs out of space stops shrinking at its longest word instead of collapsing.
| Measurement | Determined by | Typical consumer |
|---|---|---|
| min-content | Widest unbreakable run | Flex item automatic minimum, grid auto track minimum |
| max-content | Content on one line | Grid max-content track, width: max-content |
| fit-content | Available space clamped between the two | Floats, fit-content() track limits |
Intrinsic sizes are computed during layout, not from the specified values alone, so they inherit the effects of white-space, overflow-wrap, font metrics and nested boxes. Replacing a font changes a min-content size; changing the text does too. Caching must therefore be invalidated by content and style changes rather than by width changes.
Which layout modes ask which question
Block-level boxes in normal flow do not consult intrinsic sizes for their inline size: the width equation from Used Values and the Containing Block gives them the containing block’s inline size. Their intrinsic sizes matter when the box is itself sized by content, as when it is a float, an inline-block, a flex item, or a grid item in a content-sized track.
Inline-block boxes in normal flow are shrink-to-fit: their inline size is fit-content against the available space. That is why an inline-block containing a short label is narrow and an inline-block containing a sentence wraps at the container’s width instead of overflowing.
Flex items have a separate automatic minimum size. A flex item’s min-width computes to auto by default, and that auto resolves to the item’s min-content size in the main axis, not to zero. The rule exists to stop items from shrinking below their content and spilling it outside the item, but it also prevents shrinking a long word or a wide image below its intrinsic size unless min-width: 0 is set explicitly. The consequences for flex free-space distribution are substantial: an item that refuses to shrink pushes the whole deficit onto the remaining items, and onto the line’s overflow once they are at their minimums too.
Grid tracks use intrinsic sizes directly. An auto track’s minimum is the largest min-content contribution of the items in it and its maximum is the largest max-content contribution; the track grows past its content only when the grid has free space to stretch it. min-content, max-content and fit-content() are accepted as track sizes, which is the main reason the grid track sizing algorithm is multi-pass.
Replaced elements and natural sizes
A replaced element’s content supplies an intrinsic width and height. An image with a 1200 by 800 pixel source has an intrinsic size of 1200 by 800, an intrinsic ratio of 3:2, and a min-content and max-content width of 1200. CSS 2.1 specifies a fallback for replaced elements with no intrinsic dimensions and no specified size: 300 pixels wide and 150 pixels tall. That fallback is why a replaced element that fails to load still occupies a 300 by 150 box rather than collapsing.
Images with an intrinsic ratio but no intrinsic size, such as an SVG with a viewBox and no width or height attributes, report an intrinsic ratio and no natural dimensions. When one dimension is specified, the other comes from the ratio. When neither is specified, the fallback dimensions apply and the ratio is used to fit within them.
srcset and sizes complicate the natural size: the intrinsic width of the selected image depends on the density descriptor and on the resolution chosen by the browser, so the same element can contribute different intrinsic widths in different viewport conditions. Width and height attributes on the img element map to presentational hints that establish an aspect ratio before the image loads, which is why including them prevents layout shift even when CSS sets the final size.
aspect-ratio as an intrinsic-size contributor
aspect-ratio takes auto, a ratio, and optionally the auto keyword in combination: auto 16 / 9. With a plain ratio such as 16 / 9, the box uses that ratio regardless of its content. With auto 16 / 9, the box prefers the content’s natural ratio when it has one, and falls back to 16/9 otherwise.
The property works by making the ratio part of the box’s sizing rules. If one axis has a definite size, the ratio determines the other, subject to min-height and max-height clamps. If neither axis is definite, the ratio converts an intrinsic size from one axis into the other, so a box with an intrinsic width but no intrinsic height gains a height from the ratio. If a box has content that overflows the ratio-derived size, the content still overflows; the ratio does not clip or scale the content. Setting overflow: hidden or using object-fit on a replaced element handles the visible result.
.thumb {
width: 100%;
aspect-ratio: 4 / 3;
object-fit: cover; /* scales the image inside the ratio box */
}
.card {
/* Content-sized where possible, but never taller than the ratio box. */
aspect-ratio: auto 3 / 2;
max-height: 24rem;
}
aspect-ratio also affects the automatic minimum size of flex items and the intrinsic contributions used by grid. A flex item with aspect-ratio and a definite height contributes an intrinsic width derived from the ratio, so the automatic minimum can keep it from shrinking. The interaction is specified but rarely obvious from the declarations alone.
Indefinite sizes and cyclic percentages
Percentage sizes require a definite reference. During intrinsic sizing, a percentage that would resolve against a size that is itself being computed is treated as auto; the specification calls this cyclic percentage resolution. A child with width: 50% inside a shrink-to-fit parent contributes its content’s intrinsic size rather than half of a width that does not yet exist. Once the parent’s size becomes definite, the percentage resolves normally.
The same treatment applies to height: 100% chains. A percentage height resolves only if the containing block’s height is definite and does not depend on the content. An auto-height ancestor breaks the chain, and the descendant falls back to content height. Flex and grid containers with definite sizes can restore definiteness in ways that block layout does not, which is one source of differences when a design moves between layout modes.
Aspect ratios participate in this resolution as constraints rather than as sizes: a ratio can make a size definite in one axis when the other is definite, but a cyclic dependency between the two axes resolves to the intrinsic size. Containers that are sized by their contents but whose contents query the container’s size create the circularity described in Containment and Container Queries; the sizing specification resolves such cycles by treating the container’s size in that axis as indefinite, which usually means falling back to intrinsic sizes.
For boxes whose content is expensive to lay out, contain-intrinsic-size supplies a placeholder intrinsic size when the content is skipped. The property is part of the same sizing model: it substitutes for the intrinsic measurements that would otherwise require laying out the skipped subtree, and becomes observable when the box is in a content-sized track.