๐งฉ Flex Item Properties
The container sets the stage; the items decide how they fill it. This lesson covers the six properties you apply to individual flex children โ how they grow, shrink, size, align, and reorder themselves โ and demystifies the single most important shorthand in Flexbox: flex: 1.
๐ฏ Learning Objectives
By the end of this lesson, you will be able to:
- Predict how
flex-growdistributes free space among items proportionally - Explain how
flex-shrinkremoves space when the container is too small - Distinguish
flex-basis: 0fromflex-basis: autoand why it changes equal-width layouts - Read and write the
flexshorthand, including the meaning offlex: 1 - Override alignment for one item with
align-selfand reorder items withorder
Estimated Time: 30โ40 minutes โข Difficulty: Intermediate
Hands-on: Build an equal-height product card where the footer always sticks to the bottom.
In This Lesson
The Item Property Map
Flex item properties apply to the direct children of a flex container. Where container properties set the overall rules, item properties let individual children opt into different sizing and positioning. There are six:
The first four are all about size along the main axis; align-self is about cross-axis alignment of one item; and order is about visual sequence. We'll take them in that order.
flex-grow
flex-grow is a unitless proportion that says how much of the container's leftover free space an item should absorb. The default is 0 โ don't grow. Give items positive values and they share the free space in that ratio.
.item { flex-grow: 0; } /* default โ stays at its basis size */
.item { flex-grow: 1; } /* grows to claim free space */
.grow-twice { flex-grow: 2; } /* grows twice as fast as a grow: 1 item */
๐ How the browser computes it
- Lay out every item at its
flex-basissize. - Measure the leftover free space in the container.
- Sum all the
flex-growvalues, then hand each item a share of the free space equal to its grow รท the total.
The classic use is a spacer that pushes other items apart: an empty element with flex-grow: 1 soaks up all the free space, shoving whatever follows it to the far edge โ the same job the margin-left: auto trick does.
flex-shrink
flex-shrink is the mirror image of grow: it controls how much an item gives up when the items are collectively too big for the container. The default is 1 (items may shrink); set it to 0 to forbid shrinking entirely.
.item { flex-shrink: 1; } /* default โ may shrink when space is tight */
.no-shrink { flex-shrink: 0; } /* never shrink below its basis */
.shrink-fast { flex-shrink: 2; } /* gives up space twice as fast */
โ ๏ธ Shrink weighs the item's size too
Unlike grow, the shrink calculation is weighted by each item's base size, so a larger item shrinks more in absolute pixels even at the same flex-shrink value. The practical takeaway: use flex-shrink: 0 to lock a fixed sidebar or icon at its size while a neighbor absorbs the squeeze.
.sidebar {
flex: 0 0 250px; /* grow 0, shrink 0 โ stays exactly 250px */
}
.main {
flex: 1 1 auto; /* grows and shrinks to fill what's left */
}
โ ๏ธ The min-width: 0 gotcha
A flex item won't shrink below the intrinsic size of its content by default (its implied min-width is auto). If a long word or a wide child is stopping an item from shrinking, add min-width: 0 (or overflow: hidden) to let it compress.
flex-basis
flex-basis sets an item's starting main size โ the size it has before grow and shrink adjust it. It accepts a length (200px, 50%) or the keyword auto (use the item's content or explicit width/height).
| Value | Starting size |
|---|---|
auto | Based on content (or an explicit width/height) โ the default |
0 | Zero โ content size is ignored; grow alone decides the size |
200px | Exactly 200px to start |
50% | Half the container's main size to start |
๐ The 0 vs auto distinction โ the crux of equal columns
With flex-basis: auto, items start at their content width, so an item with more text begins wider and stays wider even after growing. With flex-basis: 0, every item starts from zero, so equal flex-grow values produce truly equal widths regardless of content. That's why equal columns use flex: 1 1 0 (or just flex: 1), not flex: 1 1 auto.
/* Truly equal columns, content length ignored */
.column { flex: 1 1 0; }
/* Content-aware columns, wider content = wider column */
.column { flex: 1 1 auto; }
The flex Shorthand
The flex property sets flex-grow, flex-shrink, and flex-basis in one declaration โ in that order. Prefer it over the longhands; it's more concise and it sets sensible defaults for the values you omit.
/* grow shrink basis */
.item { flex: 1 1 200px; }
/* Common one-value and two-value forms */
.item { flex: 1; } /* => 1 1 0 โ fully flexible, equal sizing */
.item { flex: auto; } /* => 1 1 auto โ flexible but content-aware */
.item { flex: none; } /* => 0 0 auto โ fully rigid */
.item { flex: 0 0 200px; }/* fixed 200px, no grow or shrink */
โ
Why flex: 1 is everywhere
flex: 1 expands to flex-grow: 1; flex-shrink: 1; flex-basis: 0;. Because every such item starts from a zero basis and grows equally, a row of flex: 1 items ends up exactly the same width, splitting the container evenly โ the single most common Flexbox pattern you'll write.
Mixing shorthand values lets you build rich layouts. A dashboard with normal, wide, and fixed widgets:
.widget { flex: 1 1 250px; } /* flexible, min basis 250px */
.widget-wide { flex: 2 1 500px; } /* grows twice as much */
.widget-fixed { flex: 0 0 200px; } /* locked at 200px */
align-self & order
align-self โ one item, its own cross-axis alignment
align-self overrides the container's align-items for a single item. It takes the same values โ auto (default, follow the container), flex-start, center, flex-end, stretch, baseline.
.toolbar { display: flex; align-items: center; }
/* This one badge drops to the bottom while the rest stay centered */
.toolbar .badge { align-self: flex-end; }
order โ visual reordering without touching HTML
Every item defaults to order: 0 and items render in source order. Assigning order values re-sorts them by that number (lowest first); ties fall back to source order. Negative values are allowed and sort before 0.
/* Mobile: main content first, sidebar after */
.sidebar { order: 2; }
.content { order: 1; }
@media (min-width: 768px) {
.sidebar { order: 1; } /* desktop: sidebar first */
.content { order: 2; }
}
โ ๏ธ order is a visual-only tool
order changes the paint order, not the DOM order. Keyboard tabbing and screen readers still follow the HTML sequence, so a big visual reorder can create a confusing, mismatched experience. Use it for presentation tweaks, not to fix content that's in the wrong order in the markup โ fix the markup instead. Stick to small, logical values like -1, 0, 1.
Hands-on: Equal-Height Card
๐๏ธ A product card with a bottom-anchored footer
Objective: Build a card whose "Add to cart" footer always sits at the bottom, so a row of cards with different text lengths still line up their footers. This is the flagship use of flex-grow on an item.
Requirements
- The card is a column flex container: image, body, footer stacked.
- The body region expands to fill the leftover height so the footer is pushed down.
- Placed in a wrapping row, cards of unequal content still align their footers.
๐ก Hint
Make the card display: flex; flex-direction: column. Then give the body flex: 1 (or flex-grow: 1) so it absorbs the free vertical space. The footer, with no grow, stays at its natural height at the bottom. Give the card a fixed flex-basis in the row so all cards are the same width.
โ Sample solution
<div class="cards">
<article class="card">
<div class="card__media">Image</div>
<div class="card__body">
<h3>Product A</h3>
<p>A short description.</p>
</div>
<div class="card__footer">
<span>$19.99</span>
<button>Add to cart</button>
</div>
</article>
<!-- more cards with longer/shorter bodies -->
</div>
.cards {
display: flex;
flex-wrap: wrap;
gap: 1.25rem;
}
.card {
display: flex;
flex-direction: column; /* column context: main axis is vertical */
flex: 1 1 260px; /* equal, wrapping columns */
border: 1px solid #ddd;
border-radius: 8px;
overflow: hidden;
}
.card__body {
flex: 1; /* grows to fill height โ footer sinks to bottom */
padding: 1rem;
}
.card__footer {
display: flex;
justify-content: space-between;
align-items: center;
padding: 1rem;
background: #f5f5f5;
}
The magic line is flex: 1 on .card__body: in a column container it grows vertically, absorbing extra height so every card's footer lands at the same baseline no matter how long the description is.
๐ฏ Quick Quiz
Question 1: What does flex: 1 expand to?
Question 2: You want three columns to be exactly equal width regardless of their text. Which is correct?
Question 3: Which statement about the order property is true?
Best Practices & Pitfalls
โ Do
- Prefer the
flexshorthand over the three longhands โ it's clearer and sets good defaults. - Use
flex: 1(basis 0) for truly equal columns; useflex: 1 1 autowhen content should influence size. - Lock fixed regions with
flex: 0 0 <size>and let neighbors absorb the flex. - Add
min-width: 0when an item refuses to shrink around long content.
โ ๏ธ Don't
- Don't assume equal
flex-growmeans equal width โ it only does with a shared, usually zero, basis. - Don't use
orderto fix content that is genuinely in the wrong sequence; fix the HTML so assistive tech gets it right. - Don't forget images need
max-width: 100%(and oftenobject-fit) or they'll blow out a flex item. - Don't set
flex-shrink: 0on many items in a tight row โ they'll overflow instead of wrapping.
Summary & Quiz
๐ Key Takeaways
flex-growshares free space proportionally;flex-shrinkremoves space when items overflow.flex-basisis the starting main size;0vsautois the difference between equal and content-aware columns.- The
flexshorthand sets grow, shrink, and basis at once โ andflex: 1means1 1 0. align-selfoverrides cross-axis alignment for one item;orderchanges visual sequence only.- A body region with
flex: 1inside a column card is how footers stay pinned to the bottom.
๐ Further Reading
- MDN โ the flex shorthand
- MDN โ Controlling ratios of flex items
- CSS-Tricks โ A Complete Guide to Flexbox
๐ What's Next?
You've now covered Flexbox end to end โ the model, the container, and the items. Next we step up to CSS Grid, the two-dimensional layout system that handles rows and columns together and pairs beautifully with the Flexbox skills you just built.
๐ Flexbox complete!
Containers, items, axes โ the whole toolkit is yours. On to the second dimension with Grid.