CSS Flexbox: Interactive Guide

Adjust a live flex container's properties with up to six boxes and watch the generated CSS update in real time, ready to copy into your own stylesheet.

Published Last reviewed

1

The Flexbox Model

Setting display: flex on a container turns its direct children into flex items laid out along a main axis, horizontal by default. Everything flexbox does is described in terms of that main axis and the cross axis running perpendicular to it; the five properties below all just position items along one or the other.

flex-direction is what decides which axis is which: in row the main axis runs left to right and the cross axis runs top to bottom; switch to column and that flips, the main axis becomes vertical. Every other property below keeps the same meaning either way, since they're defined relative to the main/cross axes, not literally to "horizontal" and "vertical."

2

Live Demo

Try it: Change the dropdowns below to see how each container property repositions every box at once; the CSS panel updates the moment you change a value.
1
2
3
4
5
6
flex-demo.css

                
3

Container Properties

These five properties (plus display: flex itself) all live on the container, not the items, and correspond directly to the dropdowns in the demo above:

PropertyWhat it controls
flex-direction Which way the main axis runs: row, row-reverse, column, or column-reverse. The -reverse variants flip the visual order without touching the underlying source order or the order property.
justify-content Spacing of items along the main axis: bunched at the start or end, centered, or spread out with space-between (no space at the outer edges), space-around (equal space around each item, so edge gaps are half-size), or space-evenly (every gap, including the edges, is the same size).
align-items Positioning of items along the cross axis. stretch (the default) makes every item fill the cross-axis size unless it has an explicit height/width set on that axis. Because the demo's boxes have a fixed 64px width and height, switching to stretch changes nothing visible here. Remove a box's cross-axis size and it would fill the container's height (in a row) or width (in a column).
flex-wrap nowrap (the default) forces every item onto one line, shrinking them if they don't fit. wrap lets items overflow onto additional lines instead.
gap Fixed spacing between items, on both axes. Modern and the preferred approach; the older alternative was margin tricks on individual items, which got messy fast once wrapping was involved.

Try switching flex-direction to column in the demo, then changing align-items: instead of moving boxes up and down, it now moves them left and right, because the cross axis rotated along with the main axis.

4

Item Properties: order, flex, and align-self

The container properties in Section 3 apply to every item at once. A handful of properties go the other way: set on an individual item, they override how that one item behaves within the container's layout. order is the one used by the live demo above.

.box-3 {
    order: -1; /* visually first, regardless of where it sits in the HTML */
}

Every flex item has a default order of 0. Items are laid out by sorting on order first, and falling back to source (HTML) order for any items that tie, which is why two untouched boxes (both still at the default 0) stay in their original relative order even after a third box elsewhere gets pulled to the front with a negative value. Critically, order changes only the visual position; it doesn't move anything in the DOM, doesn't change tab order for keyboard navigation, and doesn't change how a screen reader announces the content, which makes it purely a visual layout tool and a poor substitute for actually reordering meaningful content in the markup.

flex-grow, flex-shrink, flex-basis

Often written together as the flex shorthand, these three control how an item's size responds to the container having extra or insufficient space. flex-basis is the item's starting size before any growing/shrinking happens; flex-grow is a ratio describing how much of any leftover space the item should claim relative to its siblings; flex-shrink is the same idea in reverse, how much of a size deficit the item should absorb when there isn't enough room for every item at its basis size. flex: 1, by far the most common use, is shorthand for flex: 1 1 0%: ignore each item's natural content size and divide the container's space evenly between them.

One sizing gotcha is worth committing to memory: flex items default to min-width: auto (min-height in a column), which means an item refuses to shrink below its content's natural size no matter what flex-shrink says. When something wide and unbreakable (a long URL, a table, a <pre> block) forces the whole layout to overflow its container, the fix is min-width: 0 on the flex item. The same applies to grid items, which is why sizing grid columns with minmax(0, 1fr) instead of a bare 1fr avoids the identical overflow.

align-self overrides the container's align-items for one specific item on the cross axis only, useful for pulling a single item to the opposite end of the cross axis from all its siblings without having to restructure the container.

5

Reference

PropertyApplies toDefault
display: flexContainer
flex-directionContainerrow
justify-contentContainerflex-start
align-itemsContainerstretch
flex-wrapContainernowrap
gapContainer0
orderItem0
flex-growItem0
flex-shrinkItem1
flex-basisItemauto
align-selfItemauto (inherits align-items)