Flexbox
Before flexbox, centring a box vertically took tricks. With display: flex, it takes two declarations: justify-content and align-items.
One row or one column
Flexbox, the CSS Flexible Box Layout module, arranges a group of boxes along one line. Put display: flex on a container and its direct children, the flex items, line up side by side instead of stacking. That one declaration is enough for a menu bar, a row of buttons, or a card whose footer should stick to the bottom. Flexbox works in one dimension at a time: either a row or a column. When you need rows and columns together, grid, in the next unit, is usually the better tool.
Two axes
Everything in flexbox is described in terms of two axes. The main axis is the direction the items flow, set by flex-direction: row (the default) or column. The cross axis runs at right angles to it. justify-content distributes the items along the main axis: flex-start, center, flex-end, space-between (first and last item at the edges, equal gaps between) or space-around. align-items positions them on the cross axis: stretch (the default, all items as tall as the tallest), flex-start, center or flex-end. So a box is centred in both directions with justify-content: center and align-items: center.
.bar {
display: flex;
justify-content: space-between; /* logo left, menu right */
align-items: center; /* vertically centred */
gap: 16px; /* space between items */
}
.cards { display: flex; flex-wrap: wrap; gap: 12px; }
.card { flex: 1 1 200px; } /* grow, shrink, start at 200px */Gaps and wrapping
gap puts space between items without adding any at the outer edges, which is what you usually want and what margins make awkward. By default, flex items stay on one line and shrink to fit, even if that squashes them. flex-wrap: wrap lets them move onto a new line when there is not enough room, so a row of four cards on a laptop can become two rows of two on a tablet and a single column on a phone, with no media query.
How items grow and shrink
The flex shorthand on an item takes three values. flex-grow says how much of the leftover space the item takes compared with its siblings; flex-shrink says how willingly it shrinks when space runs out; flex-basis is its starting size before growing or shrinking. flex: 1 1 200px means start at 200 pixels, then share extra space equally with other items that also have a grow of 1. flex: 1 on its own is short for 1 1 0%, which makes all items equal widths. Give one item flex-grow: 2 and the others 1, and it takes twice their share of the leftover space.
Visual order and real order
Flexbox can change the order items appear in, with flex-direction: row-reverse or the order property, without touching the HTML. Use this with care. Keyboard focus and screen readers still follow the order in the HTML, so if the screen shows Contact before Home but Tab visits Home first, keyboard users get lost. When the order matters to meaning, change it in the HTML.
| flex container | The parent with display: flex |
| flex item | A direct child of a flex container |
| main axis | Direction of flow; set by flex-direction |
| justify-content | Distributes items along the main axis |
| align-items | Positions items on the cross axis |
| gap | Space between items, not at the edges |
| flex: 1 1 200px | grow 1, shrink 1, basis 200px |
- Which declaration turns an element into a flex container?
- display: flex
- flex: 1
- position: flex
- In a row, which property spreads items horizontally?
- justify-content
- align-items
- flex-wrap
- With flex-direction: column, what does justify-content control?
- Vertical distribution
- Horizontal distribution
- Font size
- Which value puts the first and last items at the edges with equal gaps between?
- space-between
- space-around
- center
- What is the default value of align-items?
- stretch
- center
- flex-start
- Four items have flex: 1 in a 400px container with no gaps. How wide is each?
- Three items with flex-basis 0 share 400px. One has flex-grow 2, the others 1. How wide is the big one?
- What does flex-wrap: wrap allow?
- Items move to a new line when there is no room
- Text wraps inside items
- Items overlap
- The order property puts Contact first on screen, but it is last in the HTML. What still visits it last?
- Keyboard focus and screen readers
- The mouse pointer
- Nothing
- Flexbox lays out in how many dimensions at a time?
- display: flex lines up the direct children along the main axis.
- justify-content on the main axis, align-items on the cross axis, gap between.
- flex: grow shrink basis; flex-wrap: wrap for rows that reflow; keep visual order equal to HTML order.