flex [-grow|-shrink|-basis]
These four properties control how flex items size themselves along the main axis relative to available free space. flex is a shorthand for the other three.
On this page
flex
Shorthand for flex-grow, flex-shrink, and flex-basis in that order.
Syntax
selector {
flex: <grow> <shrink> <basis>;
flex: <number>; /* sets grow; shrink defaults to 1, basis to 0 */
flex: none; /* 0 0 auto β item does not grow or shrink */
flex: auto; /* 1 1 auto β item grows and shrinks based on content */
}
Common Patterns
| Declaration | Grow | Shrink | Basis | Effect |
|---|---|---|---|---|
flex: 1 |
1 | 1 | 0 | All items share free space equally |
flex: 2 |
2 | 1 | 0 | Item gets twice as much free space as flex: 1 items |
flex: none |
0 | 0 | auto | Item stays at its natural size |
flex: auto |
1 | 1 | auto | Item grows/shrinks from its natural size |
flex: 0 0 160pt |
0 | 0 | 160pt | Fixed width, never grows or shrinks |
.sidebar { flex: 0 0 160pt; } /* fixed 160pt, does not flex */
.main { flex: 1; } /* takes all remaining space */
.equal-a { flex: 1; }
.equal-b { flex: 1; } /* equal-a and equal-b split space 50/50 */
.double { flex: 2; } /* takes twice the share of flex: 1 siblings */
flex-grow
How much a flex item grows relative to its siblings when there is extra space in the container after all items are placed at their base size.
Syntax
selector { flex-grow: <number>; } /* default: 0 */
A value of 0 means the item does not grow. Values are proportional β an item with flex-grow: 2 receives twice the extra space of an item with flex-grow: 1.
.no-grow { flex-grow: 0; } /* stays at its base size */
.grows { flex-grow: 1; } /* takes available free space */
.grows-2x { flex-grow: 2; } /* takes twice as much free space */
flex-shrink
How much a flex item shrinks relative to its siblings when the container is too small to fit all items at their base size. A value of 0 prevents shrinking entirely.
Syntax
selector { flex-shrink: <number>; } /* default: 1 */
.no-shrink { flex-shrink: 0; } /* keeps its full base size even if container is too small */
.shrinks { flex-shrink: 1; } /* shrinks proportionally (default) */
Setting flex-shrink: 0 is commonly paired with a fixed flex-basis to create items that never change size regardless of the container:
.logo { flex: 0 0 80pt; } /* fixed 80pt β shorthand for flex-shrink: 0 */
flex-basis
The initial size of the item along the main axis before flex-grow and flex-shrink are applied.
Syntax
selector { flex-basis: auto | <length>; } /* default: auto */
| Value | Description |
|---|---|
auto |
Size comes from the itemβs own width (row) or height (column); falls back to content size |
<length> |
Fixed starting size: pt, px, %, em, etc. |
0 |
Item starts at zero, so all space is distributed by flex-grow |
.auto-size { flex-basis: auto; } /* size from content */
.fixed-base { flex-basis: 200pt; } /* starts at 200pt */
.zero-base { flex-basis: 0; flex-grow: 1; } /* pure proportional sizing */
Examples
Equal-width columns
<style>
.row { display: flex; gap: 10pt; }
.col { flex: 1; padding: 12pt; background-color: #f3f4f6; }
</style>
<div class="row">
<div class="col">Column 1</div>
<div class="col">Column 2</div>
<div class="col">Column 3</div>
</div>
Fixed sidebar with flexible main
<style>
.layout { display: flex; gap: 20pt; }
.sidebar { flex: 0 0 140pt; background-color: #f3f4f6; padding: 12pt; }
.main { flex: 1; padding: 12pt; }
</style>
<div class="layout">
<div class="sidebar"><strong>Navigation</strong><p>Section 1</p><p>Section 2</p></div>
<div class="main"><h2>Content</h2><p>Takes all remaining space.</p></div>
</div>
Proportional columns (1:2:1)
<style>
.row { display: flex; gap: 8pt; }
.narrow { flex: 1; padding: 10pt; background-color: #fef9c3; }
.wide { flex: 2; padding: 10pt; background-color: #dbeafe; }
</style>
<div class="row">
<div class="narrow">25%</div>
<div class="wide">50%</div>
<div class="narrow">25%</div>
</div>
Notes
- An item without a
width, aflex-basisor aflex-growis the width of its content, as in a browser. Scryber measures the content by laying the item out before the row, and then lays the row out with that width. Content longer than the row wraps, so the item is never wider than the row. - A row of only content width items is packed at the start of the row (use
justify-contentto spread them). Before 9.8.0-beta.7 they were split into equal columns. - An item that grows, such as
flex: 1, takes the space that is left after the items with a width and the content width items. - Counters,
::beforeand::aftercontent, and links to an item are not affected by the measuring - they come from the final layout.
See Also
- flex-* β flexbox overview
- flex-direction β which axis is the main axis
- justify-content β distribute remaining space between items
- gap / row-gap / column-gap β spacing between items