Flexbox
Grow, shrink, and basis
Control how flex items claim free space or surrender space with flex-grow, flex-shrink, flex-basis, and the flex shorthand.
Flexbox sizes items in three steps. Each item starts from a base size. The browser adds them up and compares the total with the container. Then it hands out the extra room, or takes away the missing room, according to three numbers on each item.
Those numbers are flex-grow, flex-shrink, and flex-basis. The flex shorthand sets them in that order: grow, shrink, basis.
A sidebar with a fixed width next to a main column that takes the rest:
.sidebar { flex: 0 0 16rem; }
.main { flex: 1 1 30rem; }
The sidebar has grow 0 and shrink 0, so it stays at 16rem no matter what. The main column starts at 30rem, grows when there is spare room, and shrinks when the container is tight.
The shorthand values you’ll see everywhere
flex: 1 means 1 1 0. The basis is zero, so the item ignores its content width and shares free space equally with any sibling that also has flex: 1. This is how you get equal columns.
flex: auto means 1 1 auto. The item starts from its own width or content size, then grows and shrinks from there. Two flex: auto items with different content end up with different widths.
flex: none means 0 0 auto. The item keeps its natural size and never moves.
These are different layout decisions. Pick the one that matches what you want, don’t reach for flex: 1 by habit.
Grow and shrink are not symmetric
Grow factors split the positive free space in proportion. Two items with flex-grow: 1 each get half.
Shrink is weighted by the base size too. A wide item with flex-shrink: 1 loses more pixels than a narrow one with the same factor. So two shrinking items rarely lose the same amount.
The minimum size trap
A flex item has an automatic minimum size equal to its min-content size, the width of its longest unbreakable piece. A long URL or a wide image inside .main stops it from shrinking, and the row overflows the page.
The fix is to allow the item to go smaller:
.main {
min-inline-size: 0;
}
Now the item shrinks. The long content still needs somewhere to go, so add overflow-wrap: anywhere for text or max-width: 100% for images. Don’t slap overflow: hidden on the item to make the symptom vanish. Find which minimum is holding the size and fix that.
Try it: build the sidebar and main layout, then compare flex: 1, flex: auto, and flex: none on the main column while watching the sizing info in the DevTools Flexbox panel. Paste a long URL into the main column and watch the row break, then add min-inline-size: 0 and watch it recover.
Lesson completed