In-Depth Article
Flexbox Sizing Explained: `flex-grow`, `flex-shrink`, `flex-basis`, and Why Width Is Not the Whole Story
Follow the Flexbox sizing algorithm step by step so you can predict how free space, negative space, and min-size clamping affect each item.
If Flexbox alignment is the visible part of the model, sizing is the part that causes the real confusion.
The usual mistake is assuming width is the final answer inside a flex container. It often is not. Flex items establish a starting size, negotiate extra space, give up space when necessary, and then get clamped by minimums and maximums. This article makes that sequence easier to reason about. It works best after Flexbox fundamentals and alignment and before classic Flexbox layout patterns.
1. Why Flexbox sizing feels weird at first
In normal block flow, a declared width can feel like a clear answer.
In Flexbox, that width may be only one input into a larger calculation. The browser still has to decide:
- each item's starting size
- whether the line has extra space or not enough space
- which items are allowed to grow or shrink
- whether minimum or maximum constraints override the result
That is why these two items do not behave remotely the same way:
.item-a {
flex: 1 1 0;
}
.item-b {
flex: 0 0 auto;
}
Those values are not cosmetic. They are describing two completely different roles in the sizing algorithm.
2. flex-basis is the starting point
The easiest way to think about flex-basis is this:
Before Flexbox starts distributing or reclaiming space, what size should this item begin from on the main axis?
In practice:
flex-basis: autousually starts from content size or a declared widthflex-basis: 0tells Flexbox to start from a much more distribution-driven positionflex-basis: 18remgives the item a meaningful preferred size before negotiation begins
That is why this is usually clearer than splitting the intent across several properties:
.sidebar {
flex: 0 0 18rem;
}
.main {
flex: 1 1 24rem;
}
You can read the relationship immediately:
- the sidebar is fixed
- the main area prefers to be wide
- the main area may still grow and shrink
3. flex-grow only distributes leftover space
When the flex line has extra room, flex-grow decides how that room is shared.
.sidebar {
flex: 0 0 18rem;
}
.main {
flex: 2 1 0;
}
.extras {
flex: 1 1 0;
}
If the fixed sidebar takes its width first, the remaining space is then shared between .main and .extras in a 2:1 ratio.
That is an important detail:
2does not mean double the final width- it means double the share of the leftover free space
This is why a large-looking panel can dominate without having an explicit width. The growth ratio gave it more room to claim after the base sizes were established.
4. flex-shrink is where the browser starts taking space back
When the items do not fit, Flexbox does not simply subtract the same number of pixels from everyone.
Shrink behavior depends on both:
- the item's
flex-shrink - the size it started from
That is why larger items often lose more pixels than smaller ones even when their shrink factor is the same. The browser is shrinking proportionally from the initial sizes, not applying a flat tax.
This is also why big text-heavy regions often feel "punished" first in a tight row. They had more size to give up, at least until they hit a minimum constraint.
5. The min-size trap explains many production bugs
A very common bug looks like this:
- you have a sidebar and a main panel
- the main panel contains a long code block or long unbroken text
- you expect the main panel to shrink
- the whole layout overflows instead
Often the missing fix is not flex-shrink. It is the minimum size:
.layout {
display: flex;
}
.layout__sidebar {
flex: 0 0 16rem;
}
.layout__main {
flex: 1 1 auto;
min-width: 0;
}
That single line, min-width: 0, solves an absurd number of real UI issues.
For column layouts, the twin fix is often min-height: 0, especially when a child needs to become scrollable.
6. A worked example with actual numbers
Suppose a row is 900px wide and contains three items:
- item A:
flex: 1 1 200px - item B:
flex: 2 1 200px - item C:
flex: 1 1 100px
The total basis is 500px, so the line has 400px of positive free space.
The growth factors are 1 : 2 : 1, which means the free space is split into four shares:
- item A gets
100px - item B gets
200px - item C gets
100px
So the final sizes are roughly:
- item A:
300px - item B:
400px - item C:
200px
This kind of quick mental math is enough to explain a lot of real interfaces. Once you do it a few times, Flexbox stops feeling magical and starts feeling negotiable.
7. Why width and flex-basis seem to disagree
One of the most common confusing cases looks like this:
.item {
width: 20rem;
flex: 1 1 auto;
}
Developers often read width: 20rem as a promise. Inside Flexbox it is often better understood as part of the starting-size calculation when the basis is auto.
That means the item can still:
- grow
- shrink
- get clamped by minimums
If what you really want is "this item prefers about 20rem, but it is still flexible," then this is usually more honest:
.item {
flex: 1 1 20rem;
}
Now the layout contract is visible in one place.
8. The shorthand values worth actually remembering
You do not need every Flexbox combination. These cover most production work:
flex: 1 1 0for evenly shared flexible spaceflex: 1 1 autowhen content should influence the starting sizeflex: 0 0 autofor fixed-size itemsflex: 0 1 autowhen an item should keep its natural size but may shrink if needed
The most useful habit is not memorizing all shorthands. It is learning to read them as a sentence:
- may grow?
- may shrink?
- where does it start?
9. A debugging sequence that works under pressure
When a flex item feels wrong, inspect these in order:
- What is the
flex-basis? - Is the item allowed to grow?
- Is the item allowed to shrink?
- Is content forcing a larger intrinsic minimum?
- Do I need
min-width: 0ormin-height: 0?
That sequence is much faster than toggling random properties and hoping the layout behaves.
10. The mental model worth keeping
Flexbox sizing is not difficult because it is random. It is difficult because several sensible rules are active at once:
- a starting size
- growth behavior
- shrink behavior
- intrinsic minimums
- explicit limits
Once you separate those layers, Flexbox becomes far more predictable.
The most useful next step is to apply that model in classic Flexbox layout patterns or compare it directly with Grid in Flexbox vs Grid decision guide.
Reviewed by
DevDepth Editor
Editor and frontend engineering writer
DevDepth publishes practical guides on React, Next.js, TypeScript, frontend architecture, browser APIs, and performance optimization.
Each article should be reviewed for technical accuracy, code clarity, metadata quality, and internal-link fit before it goes live.
Last editorial review: 2026-03-17