CSS Flexbox Cheatsheet - Flexbox Layout Reference

For developers who have fought with floats or inline-block for centering and equal-width rows. Flexbox is the modern way to lay out a single row or column quickly. The recurring confusion is that Flexbox is one-dimensional and that justify-content and align-items act on different axes. By the end you can center anything, build a toolbar and a wrapping card row, and control item sizing with flex-grow/flex-shrink/flex-basis without trial and error.

Web Services·44 commands·Last updated 2026-07-21
cssflexboxLayoutFrontend

Typical Use Case

For front-end developers doing layout work who would rather not fight float or absolute positioning again. Almost all of the difficulty in Flexbox lives in one distinction: flex-direction sets the main axis, align-items acts on the cross axis, so flip the main axis and alignment flips with it. Container properties, main-axis distribution, cross-axis alignment and item-level flex shorthand sit in separate layers, followed by ready-made combinations for centring, sticky footers and responsive card grids, and why flex: 1 is not 1 1 auto.

Container Properties 8

display: flex
Enable flex layout (block-level)
display: inline-flex
Enable flex layout (inline-level)
flex-direction: row
Main axis = row, horizontal (default)
flex-direction: column
Main axis = column, vertical
flex-direction: row-reverse
Row, reversed order
flex-direction: column-reverse
Column, reversed order
flex-wrap: wrap
Allow wrap (default nowrap)
flex-flow: row wrap
Shorthand for direction + wrap

Gap & Main-axis Alignment 8

gap: 16px
Gap between items (row & column)
row-gap: 16px
Row gap only
column-gap: 16px
Column gap only
justify-content: flex-start
Start of main axis (default)
justify-content: center
Center on main axis
justify-content: flex-end
End of main axis
justify-content: space-between
Space between, ends flush
justify-content: space-around
Equal space around each item

Cross-axis Alignment 7

justify-content: space-evenly
All gaps exactly equal
align-items: stretch
Stretch to fill cross axis (default)
align-items: flex-start
Start of cross axis
align-items: center
Center on cross axis
align-items: flex-end
End of cross axis
align-items: baseline
Align on baseline
align-content: center
Cross-axis alignment of wrapped lines

Item Properties 10

flex-grow: 1
Grow factor, 0 = no grow (default)
flex-shrink: 1
Shrink factor, 0 = no shrink (default 1)
flex-basis: 200px
Initial size (default auto)
flex: 1
Shorthand: 1 1 0%, share free space
flex: 0 0 200px
Shorthand: no grow/shrink, fixed 200px
flex: auto
Shorthand: 1 1 auto
flex: none
Shorthand: 0 0 auto, no grow/shrink
align-self: flex-end
Override align-items for one item
order: 1
Display order, default 0, can be negative
order: -1
Move to the front

Common Patterns 6

justify-content: center; align-items: center
Horizontal & vertical center
justify-content: space-between
Space-between (navbar left/right)
flex: 1
Share remaining space
margin-left: auto
Push item to end of main axis
min-height: 100vh
Sticky footer with column (child flex:1)
flex: 1 0 auto
Fixed base, no shrink (sidebar)

Responsive Tips 5

flex-wrap: wrap
Auto wrap when window narrows
flex-basis: 200px; flex-grow: 1
Responsive card grid
flex-wrap: wrap-reverse
Reverse wrap layout
@media (max-width: 768px) { flex-direction: column }
Switch to column on mobile
flex: 1 1 100%
Fill full row, force wrap

Parameter matrix

ParameterEffectExample
display: flexTurns on flex layout; the container becomes a block-level boxdisplay: flex
display: inline-flexTurns on flex layout; the container participates in inline-level flowdisplay: inline-flex
flex-direction: rowMain axis runs horizontally, the defaultflex-direction: row
flex-direction: columnMain axis runs vertically, which makes the cross axis horizontalflex-direction: column
flex-direction: row-reverseMain axis stays horizontal but items are laid out in reverseflex-direction: row-reverse
flex-direction: column-reverseMain axis runs vertically with the item order reversedflex-direction: column-reverse
flex-wrap: wrapLets items wrap; nowrap, the default, never wrapsflex-wrap: wrap
flex-wrap: wrap-reverseWrapping starts from the cross-axis end rather than the startflex-wrap: wrap-reverse
flex-flow: row wrapShorthand that sets flex-direction and flex-wrap togetherflex-flow: row wrap
gap / row-gap / column-gapSpacing between items, controllable per axisgap: 16px
justify-content: flex-startPacks items at the main-axis start, the defaultjustify-content: flex-start
justify-content: centerCentres items along the main axisjustify-content: center
justify-content: flex-endPacks items at the main-axis endjustify-content: flex-end
justify-content: space-betweenFlush at both ends, with the slack split between the itemsjustify-content: space-between
justify-content: space-aroundEqual space around every item, leaving less at the two endsjustify-content: space-around
justify-content: space-evenlyEvery gap is exactly equal, the two outer ones includedjustify-content: space-evenly
align-items: stretchStretches items to fill the cross axis, the defaultalign-items: stretch
align-items: centerCentres items on the cross axisalign-items: center
align-items: baselineAligns items by their text baselinealign-items: baseline
align-content: centerDistributes whole lines along the cross axis; only meaningful once wrapping is onalign-content: center
flex-growGrowth factor, where 0 disables growingflex-grow: 1
flex-shrinkShrink factor, whose default of 1 allows items to compressflex-shrink: 1
flex-shrink: 0Forbids compression and holds the base sizeflex: 0 0 200px
flex-basis: 200pxInitial main-axis size before the free space is distributedflex-basis: 200px
flex: 1Shorthand for 1 1 0%, splitting the free space evenlyflex: 1
flex: 0 0 200pxShorthand for neither growing nor shrinking, pinned at 200pxflex: 0 0 200px
flex: autoShorthand for 1 1 auto, which distributes space on top of the content sizeflex: auto
flex: noneShorthand for 0 0 auto, no flexing whatsoeverflex: none
flex: 1 1 100%Takes a full basis so the item fills the line and forces the next one onto a new rowflex: 1 1 100%
flex: 1 0 autoA fixed basis with shrinking switched off, the usual sidebar recipeflex: 1 0 auto
align-selfOverrides the container's align-items for one item onlyalign-self: flex-end
orderVisual placement order; it defaults to 0 and may be negativeorder: -1
margin-left: autoUses margin to push the item to the main-axis endmargin-left: auto
min-height: 100vhCombines with a column container and flex: 1 to pin the footer to the bottommin-height: 100vh
@media (max-width: 768px) { flex-direction: column }Flips a horizontal layout into a vertical one on narrow screens@media (max-width: 768px) { flex-direction: column }

Common pitfalls

SymptomThe parent says flex: 1 yet the child is squashed flat, so content overflows or the height collapses.

Causeflex: 1 means 1 1 0%, and that shrink factor of 1 lets the item compress below its content size; a vertical main area with no explicit basis simply gets squeezed out.

FixUse flex: 1 0 auto when the item must not compress, or pair flex-grow: 1 on the child with min-height: 100vh on the parent for the vertical case.

Symptomalign-items is on the container, yet nothing looks horizontally centred.

CauseThe container is a column, so the main axis became vertical and the cross axis is now horizontal; align-items controls exactly that axis, while you meant the vertical one.

FixIn a column container use justify-content: center for vertical centring, and in a row container use align-items: center for the same job.

SymptomIn a wrapping flex container the lines clump together and justify-content has no effect on them.

Causejustify-content distributes items along the main axis; where the lines sit as a whole is align-content job.

FixGive the container an align-content value such as center, and confirm flex-wrap: wrap is actually in effect.

Symptomflex-direction and gap were added to an item and nothing whatsoever happened.

CauseThose properties belong to the container but were written on the child; an item only accepts flex, flex-basis, align-self, order and similar item-level properties.

FixMove flex-direction, flex-wrap, gap and justify-content onto the parent and leave the child with flex and align-self.

SymptomAfter reordering with order, Tab focus no longer follows the visual order.

Causeorder changes only the visual placement; the DOM and focus order are untouched, so screen readers and keyboard navigation still follow document order.

FixSort in the DOM itself instead of faking it with order, and if you must use it, check keyboard reachability.

Symptomflex-wrap: wrap plus flex-basis does not wrap: cards get squashed as the window narrows.

CauseAn item min-width defaults to auto, so long content forbids compressing below its own width and the container never sees a reason to wrap.

FixAdd min-width: 0 to the card, or a content-appropriate minimum, so flex-basis can actually drive the wrapping.

SymptomThe footer is not pinned and on a short page the whole document collapses.

CauseOnly the footer got margin-top: auto, but the parent is not a flex container or has no min-height.

FixGive the parent display: flex; flex-direction: column; min-height: 100vh and let the main region carry flex: 1.

Troubleshooting

  1. 1Confirm the container really entered flex layout

    display: flex

    If children still lay out as ordinary blocks, the declaration never reached the real parent, so check that the selector matches.

  2. 2Use justify-content to confirm main-axis centring

    justify-content: center; align-items: center

    Both together centre horizontally and vertically, but only after you know whether flex-direction is row or column.

  3. 3Verify that wrapping takes effect

    flex-wrap: wrap; flex-basis: 200px; flex-grow: 1

    This set of values forms a responsive card grid: a 200px basis, growing when there is room and wrapping when there is not.

  4. 4The full container recipe for a sticky footer

    display: flex; flex-direction: column; min-height: 100vh

    Add flex: 1 to the main region so the footer is pushed to the bottom even on a short page.

  5. 5Switch to a single column on narrow screens

    @media (max-width: 768px) { flex-direction: column }

    At 768px and below the main axis turns vertical, stacking what was side by side.

  6. 6Override alignment for a single item

    align-self: flex-end

    Useful for pushing one button to the end inside a container that otherwise centres everything.

Command Examples

Center on both axes

.box { display: flex; justify-content: center; align-items: center; height: 240px; }

justify-content works along the main axis and align-items along the cross axis. With only display: flex everything piles into the top-left corner, which reads as the stylesheet not loading at all.

Two-ended navbar with one item pushed to the end

.nav { display: flex; align-items: center; justify-content: space-between; } .nav .logout { margin-left: auto; }

space-between behaves like flex-end with exactly two children, but redistributes as soon as the child count changes. Use gap or margin-left: auto so the spacing is not hostage to the DOM structure.

Responsive card grid: wrap with a basis and grow

.grid { display: flex; flex-wrap: wrap; gap: 16px; } .grid > .card { flex: 1 1 200px; } @media (max-width: 768px) { .grid { flex-direction: column; } }

flex: 1 1 200px uses 200px as the basis and allows growth and shrink, wrapping once the container runs out of width — replacing most hand-written percentage breakpoints.

Sticky footer: the content area grows with flex: 1

body { display: flex; flex-direction: column; min-height: 100vh; } main { flex: 1; }

flex: 1 really means 1 1 0%: the item is computed at zero and then given all leftover space, which is what keeps the footer pinned to the viewport bottom instead of floating mid-page under short content.

Reorder visually with order and lay out wrapped lines

.grid { display: flex; flex-wrap: wrap; align-content: center; gap: 8px; } .grid .featured { order: -1; }

order changes visual sequence only, not DOM or tab sequence. Treating it as the accessibility fix leaves keyboard and screen-reader users reading in the wrong order.

Common Pitfalls

  • Flex items default to min-width: auto, so a long URL, a nowrap code block, or a table can blow out the container and refuse to shrink — an inexplicable horizontal scrollbar. Add min-width: 0 to let inner text ellipsize or wrap.
  • flex: 1 means 1 1 0%, not "split the content width". It lays out differently from flex: 1 1 auto whenever a content basis exists, so switching auto to 0% visibly shifts elements that used to line up.
  • After flex-wrap: wrap, the default align-content: stretch spreads the lines across the container height, which looks like margin being ignored. Set align-content: flex-start for tight row spacing.
  • Mixing margin and gap on the same axis stacks two mechanisms, and margin does not participate in leftover-space distribution — hence a mysterious extra gap after the last item. Pick one per axis.
  • A flex container establishes a new formatting context, so position: absolute children are contained by the container, not the viewport. Dropdowns and popovers that rely on viewport positioning jump once moved inside.
  • overflow: hidden on the flex container only clips what spills out; the container still sizes to its content minimum, so the parent layout is still pushed. Constrain the items with min-width/min-height instead.

Tips

  • flex: 1 is shorthand for flex: 1 1 0% — it divides the remaining space equally.
  • align-items aligns on the cross axis; with flex-direction: column the cross axis becomes horizontal.
  • The gap property replaces the old margin trick, setting item spacing more cleanly.
  • flex-wrap: wrap combined with flex-basis enables responsive grid-like layouts.
  • Prefer the flex shorthand; setting flex-grow/shrink/basis separately easily overrides intended behavior.

FAQ

What does flex: 1 actually expand to, and why does it eat up the leftover space?

flex: 1 is shorthand for flex: 1 1 0%, the three numbers being flex-grow, flex-shrink and flex-basis. Because flex-basis is 0%, the item starts at zero size, so the container treats the entire main-axis space as free space and hands it out in the grow ratio 1:1 — hence the equal-width look. Compare flex: auto (1 1 auto), which keeps the content intrinsic size so short items look narrower, and flex: 0 0 200px, which opts out of growing and shrinking entirely and pins the item at 200px.

Why does my container collapse to content height after I set align-items: center?

Because align-items controls the cross axis, and which axis is cross is decided by flex-direction. With the default flex-direction: row the cross axis is vertical, so align-items: center sizes each item to its content and centers it, collapsing the container to the tallest child. The default align-items: stretch is what makes items fill the container height. A related trap: under flex-direction: column the cross axis is horizontal, so align-items: center centers horizontally and vertical centering requires justify-content: center.

How do I make a card list reflow into a responsive grid without any media query?

The trick is flex-wrap: wrap plus flex-basis. Set the container to display: flex; flex-wrap: wrap; gap: 16px and give each card flex: 1 1 200px — flex-basis: 200px supplies the ideal width, flex-grow: 1 lets the cards on a line stretch to fill the row, and flex-shrink: 1 allows them to compress. On a wide viewport they fill one stretched row; once the viewport can no longer fit 200px, they wrap to the next line, giving you a responsive grid with zero @media rules.

How do space-between, space-around and space-evenly differ visually?

All three are justify-content values distributing leftover main-axis space, but they divide it differently. space-between pins the first and last item to the edges and splits the rest evenly — the classic navbar distribution. space-around gives every item equal spacing on both sides, so the outer margins are half the interior gaps. space-evenly makes every gap identical, including the gaps at the container edges. When a card row or button group looks like its edge padding does not match the inner spacing, switching among these three is the fix.

How do I build a sticky footer that sits at the bottom only when content is short?

Give the outer wrapper display: flex; flex-direction: column; min-height: 100vh so the main axis becomes vertical, then set the main content area to flex: 1 — its flex-grow consumes all leftover height and pushes the footer to the bottom. When content exceeds one viewport the wrapper simply grows and the footer follows the content instead of overlapping it. If the footer gets squashed because flex-shrink applies, give the content area flex: 1 0 auto so it keeps its base size and is not compressed.

Official References

Each command links to its official documentation below, so you can verify the latest usage and read deeper.

Maintained by LaoHand

Publicly updated on Jul 21, 2026, continuously proofread against official docs.

Contact Us

Wrong command or description? Send us corrections, business inquiries or product feedback by email.

Contact Us