Flexbox Advanced
Advanced flexbox uses the flex-grow , flex-shrink , and flex-basis shorthand to control exactly how items share leftover space and reorder, letting you build production layouts like sticky footers, the holy-grail page, and equal-height card grids.
Learn Python, JavaScript, Java and more with free interactive lessons, real projects and AI-powered help. Beginner-friendly.
Part of the free HTML & CSS course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.
By the end of this lesson you'll control exactly how flex items grow, shrink, and reorder themselves — and use that control to build the layouts real apps ship with: a sticky footer, the holy-grail page, and equal-height responsive card grids.
A flex container is a row of passengers sharing a bench seat. flex-basis is how much room each person needs before anyone budges. flex-grow is appetite for the empty space — a passenger with flex-grow: 2 spreads out into twice as much of the leftover bench as a neighbour on flex-grow: 1 .
flex-shrink is who gives way when the bench gets crowded: a higher number means "I'll squeeze in first." So the flex shorthand — grow shrink basis — is really just three answers to: how big do I start, how eagerly do I expand, and how willingly do I compress? Nail those three and every layout in this lesson becomes obvious.
Three properties decide how a flex item is sized. flex-basis is the item's starting size along the main axis (its width in a row). flex-grow says how much of any leftover space it absorbs, as a ratio against its siblings. flex-shrink says how much it gives up when there isn't enough room. You almost always set all three at once with the flex shorthand.
Run the worked example. The same three boxes are shown with different flex values so you can see grow ratios, a fixed item, and a basis-driven start size side by side.
align-items aligns every item on the cross axis. When you want one item to break ranks, align-self on that single child overrides the container's alignment just for it — handy for pushing one badge to the top while the rest sit centred.
order changes the visual position of an item without touching the HTML. Items sort by their order value (default 0 ), low to high. It is perfect for reordering on different screen sizes — but remember it only moves things visually, so keyboard and screen-reader order still follow your HTML.
By default flex items stay on one line and shrink to fit. Set flex-wrap: wrap and items that don't fit flow onto a new line instead — this is what turns a flex row into a responsive grid. Pair it with gap , which adds consistent spacing between items (and between wrapped rows) without the margin headaches.
Once items wrap onto multiple lines, align-content spaces those lines along the cross axis — think of it as justify-content but for whole rows. It does nothing on a single-line container, which trips up a lot of people. Run the example and shrink the preview to watch items wrap and the rows space out.
Real layouts are flex containers inside flex containers. The classic "holy grail" — header, two sidebars, a main column, and a footer — is just a vertical flex column whose middle row is itself a horizontal flex row. The outer column uses flex: 1 on the middle band so it fills the height; the inner row uses fixed-basis sidebars and a flex: 1 main.
Note min-width: 0 on the main column — without it, long content would refuse to shrink and blow out the layout (more on that in Common Errors). On narrow screens, flex-wrap and a media query collapse everything into a single column.
Cards with different amounts of text usually end up different heights — ugly. Flexbox fixes it twice over. First, align-items: stretch (the default on the cross axis) makes every card in a row the same height automatically. Second, make each card itself a vertical flex column and put margin-top: auto on the footer button — the auto margin soaks up spare space and pins the button to the bottom, so buttons line up across cards of any length.
Build a two-column row: a rigid 220px sidebar that never resizes, and a main column that fills the rest. Fill in the blanks marked ___ , run it, and check the expected result in the comments.
Turn a flex row into a wrapping grid with even spacing, then make the "featured" tile jump to the front using order . Fill in the blanks and verify the expected behaviour in the comments.
Support is faded now — only an outline is given. Build a row of pricing cards that stay equal height with their buttons aligned along the bottom. Use the worked examples in sections 3 and 5 as your reference if you get stuck.
You can now bend Flexbox to any layout. The essentials:
Next up: CSS Grid Level 2 , where you'll handle true two-dimensional layouts that Flexbox can't do alone.
Practice quiz
The flex shorthand sets three properties in which order?
- flex-basis, flex-grow, flex-shrink
- flex-grow, flex-shrink, flex-basis
- flex-shrink, flex-grow, flex-basis
- flex-grow, flex-basis, flex-shrink
Answer: flex-grow, flex-shrink, flex-basis. The flex shorthand is flex: <grow> <shrink> <basis>.
What does flex: 1 expand to?
- 1 1 auto
- 1 0 0%
- 1 1 0%
- 0 1 100%
Answer: 1 1 0%. flex: 1 is shorthand for flex: 1 1 0% — grow 1, shrink 1, basis 0%.
What does flex-grow control?
- How much of the leftover free space an item absorbs relative to siblings
- How small an item can shrink
- The item's starting size before space is distributed
- The item's visual order
Answer: How much of the leftover free space an item absorbs relative to siblings. flex-grow is the ratio of leftover space an item takes compared with its siblings.
What does flex-basis define?
- The item's final fixed width
- The item's starting size along the main axis before grow/shrink are applied
- The gap between items
- Whether the item wraps
Answer: The item's starting size along the main axis before grow/shrink are applied. flex-basis sets the initial main-axis size before flex-grow and flex-shrink redistribute space.
Which value creates a rigid 200px sidebar that never grows or shrinks?
- flex: 1 1 200px
- flex: 0 0 200px
- flex: auto
- flex: 1 0 0%
Answer: flex: 0 0 200px. flex: 0 0 200px means no grow, no shrink, and a fixed 200px basis.
When does align-content have a visible effect?
- Only when items are wrapped onto multiple lines
- On any single-line flex container
- Only when flex-direction is row
- Only when justify-content is set
Answer: Only when items are wrapped onto multiple lines. align-content distributes wrapped lines, so it only does something with multiple lines (flex-wrap: wrap).
What does the order property do to a flex item?
- Changes its visual position only, not its DOM/tab order
- Removes it from the layout
- Changes both its visual and its keyboard/screen-reader order
- Sorts items alphabetically
Answer: Changes its visual position only, not its DOM/tab order. order changes only the visual position; focus and screen-reader order still follow the HTML.
Why might a flex item overflow its container instead of shrinking?
- Because flex-shrink defaults to 0
- Because items have min-width: auto by default, refusing to shrink below their content
- Because gap is too large
- Because justify-content is set to center
Answer: Because items have min-width: auto by default, refusing to shrink below their content. The default min-width: auto stops an item shrinking past its content; min-width: 0 fixes it.
How does margin-top: auto on a button help build equal-height cards?
- It centers the button horizontally
- In a flex column it absorbs spare space, pushing the button to the bottom so buttons align across cards
- It removes the card's padding
- It makes the card taller than its content
Answer: In a flex column it absorbs spare space, pushing the button to the bottom so buttons align across cards. An auto margin soaks up free space in a flex column, pinning the button to the bottom edge.
What does align-self do?
- Overrides align-items for a single flex item on the cross axis
- Aligns the whole container on the page
- Sets the main-axis distribution
- Reverses the flex direction
Answer: Overrides align-items for a single flex item on the cross axis. align-self overrides the container's align-items for that one item on the cross axis.