flex-grow and flex-shrink Explained
flex: 1 is probably the most copied declaration in CSS, and most people who use it could not say exactly what it does. That is fine until a layout misbehaves: one column refuses to shrink, two items with the same flex-grow end up different widths, a sidebar squashes instead of the main content. All of these follow from two short algorithms — how flexbox distributes free space when there is room, and how it takes space away when there is not. Once those are clear, choosing flex values becomes deliberate. This page walks through both algorithms, the minimum-size rule that overrides them, and the handful of flex values worth memorising. It belongs to Flexbox Layout Patterns in the Mastering Container Queries & Responsive Layouts guide.
Step one: place the bases
Every flex item starts at its flex basis: the flex-basis value if set, otherwise its width (or height in a column), otherwise its content size. The browser adds up the bases plus gaps and compares the total with the container's size. If there is space left over, the items grow. If the total overflows, the items shrink. Only one of the two happens in any layout pass. flex-basis vs width covers how the basis is chosen.
Growing: free space shared by ratio
When there is free space, it is divided among the items in proportion to their flex-grow values. An item with flex-grow: 0 receives none. If two items have flex-grow: 1 and one has flex-grow: 2, the free space is split into four shares: one each for the first two, two for the third. The shares are added to each item's basis — which is why flex-grow: 2 does not mean "twice as wide", only "twice as much of the leftover".
To make items proportional to their grow values, give them a zero basis: flex: 2 1 0 and flex: 1 1 0. With nothing to start from, the whole container is free space, and the final widths are exactly 2:1.
Shrinking: overflow taken by weighted ratio
When the bases overflow, the overflow is removed from the items — but not simply in proportion to flex-shrink. Each item's share of the reduction is proportional to its flex-shrink multiplied by its flex basis. A 400-pixel item and a 100-pixel item, both with flex-shrink: 1, lose pixels in a 4:1 ratio. The rule makes sense: large items can afford to give up more, and small items do not collapse to nothing while large ones barely change.
Setting flex-shrink: 0 exempts an item entirely; it stays at its basis and the others absorb all of the overflow. That is the standard way to keep a fixed-width sidebar or an icon from being squeezed.
The complete implementation
The demo shows the common layout of a fixed sidebar, a flexible main area and a secondary panel. Resize the frame to see how each item responds.
.layout {
display: flex;
gap: 1rem;
}
.layout__nav {
flex: 0 0 12rem; /* never grows, never shrinks: fixed 12rem */
}
.layout__main {
flex: 1 1 20rem; /* starts at 20rem, takes all spare space, shrinks first */
min-inline-size: 0; /* allow shrinking below long content */
}
.layout__aside {
flex: 0 1 16rem; /* 16rem when it fits, shrinks when it must, never grows */
}
At wide sizes, the navigation stays at 12rem, the aside stays at 16rem, and the main area takes everything else because it is the only item that grows. As the frame narrows, overflow is shared between main and aside in proportion to basis × shrink, so the 20rem main area gives up more than the 16rem aside. The navigation never changes.
The key technique: the automatic minimum size
Shrinking has a hard floor that surprises everyone once. A flex item's minimum main size defaults to auto, which for most items resolves to its min-content size: the width of its longest word, widest image or fixed-width child. No amount of flex-shrink pushes an item below that floor. A main column containing a long URL or a wide <pre> block therefore refuses to shrink, and the layout overflows its container.
The fix is min-inline-size: 0 (or min-width: 0) on the item, which removes the automatic floor, usually combined with overflow-wrap: anywhere or scrolling for the offending content. Setting overflow to anything other than visible also removes the floor, because scroll containers do not use the content-based minimum. Preventing Flex and Grid Overflow covers the patterns in depth.
Growing on wrapped lines
With flex-wrap: wrap, the algorithms run once per line, not once for the whole container. Items are first broken into lines based on their bases; then free space on each line is shared only among the items on that line. That is why the last line of a wrapping row often looks different: two items on the final line split its whole width between them, while four items on a full line split a much smaller remainder. If every card should be the same width regardless of line, flexbox is the wrong tool — a grid with repeat(auto-fill, minmax(…)) keeps columns consistent across rows.
Seeing the numbers in DevTools
Browser DevTools show the algorithm's results directly. In Chromium and Firefox, selecting a flex item shows its basis, the amount it grew or shrank, and whether it hit its minimum size — Firefox labels this explicitly as the item being "clamped to its minimum size". When a layout does not behave as the arithmetic above predicts, the minimum-size clamp is almost always the reason, and the panel confirms it in one glance.
Flex values worth memorising
The flex shorthand sets grow, shrink and basis together. Four values cover nearly every case:
flex: 1— equals1 1 0%. Zero basis, so every item shares the whole container. Items withflex: 1end up equal widths regardless of content, subject to their minimum sizes.flex: auto— equals1 1 auto. Content-sized basis, then leftover space shared. Items with more content stay wider.flex: none— equals0 0 auto. Content-sized and rigid.flex: 0 0 <length>— a fixed-size item, such as a sidebar.
The default, if you set nothing, is flex: 0 1 auto: items do not grow, may shrink, and start from their content size. That default is why a row of items without any flex declarations sits at the start of the container and only compresses when it runs out of room.
Growing and shrinking in columns
Everything above applies to flex-direction: column, but column containers usually have no definite height, so there is no free space to share and nothing to shrink against: the container simply grows to fit its items. flex-grow in a column only has an effect when the container has a height, such as a full-viewport layout with min-block-size: 100dvh. That is the basis of the sticky-footer pattern in Sticky Footer With Flexbox and Grid.
Browser support
Flexbox, the flex shorthand and the automatic minimum size behave consistently in every current browser. The gap property for flex containers is also supported everywhere current; older browsers that predate it lay out the items without spacing, so Flexbox Gap and Spacing discusses margin-based fallbacks if very old engines matter. The min-content keyword used in related sizing is supported in Chrome 46+, Edge 79+, Firefox 66+ and Safari 11+.
FAQ
How does flex-grow divide space?
The free space left after every item's flex-basis is placed is split in proportion to the flex-grow values. Items with flex-grow: 2 receive twice as much of the leftover space as items with flex-grow: 1, not twice the final width.
Why do my items with equal flex-shrink shrink by different amounts?flex-shrink is weighted by each item's flex-basis. The overflow is distributed in proportion to flex-shrink multiplied by basis, so a large item gives up more pixels than a small one with the same flex-shrink value.
Why won't my flex item shrink below its content?
Flex items have an automatic minimum size of min-content in the main axis. Long words, images or fixed-width children set a floor the item cannot shrink past. Set min-inline-size: 0 or overflow other than visible to remove it.
What is the difference between flex: 1 and flex: auto?flex: 1 sets the basis to 0, so all free space is shared and items end up equal widths regardless of content. flex: auto keeps the content-based basis and shares only the leftover space, so items with more content stay wider.
Related
- Flexbox Layout Patterns — the parent guide.
- flex-basis vs width — where each item starts.
- flex-wrap for Intrinsic Responsive Rows — growing items across wrapped lines.
- Preventing Flex and Grid Overflow — the minimum-size floor in practice.
Related articles
More pages in the same section.