Introduction
For years, centring something vertically on a web page was a running joke, solved with fragile tricks. Flexbox ended that. It is designed for arranging items along a single line, and it handles the awkward questions about how to share out space, which used to take a page of arithmetic.
How it works
Add display: flex to a container. Its direct children become flex items, and they line up in a row.
Two axes. The main axis runs in the direction of the items, and the cross axis runs across it. flex-direction: row is the default, and makes the main axis horizontal. With flex-direction: column the main axis points downward. Everything else in flexbox is defined in terms of these axes, so this is the part to learn properly.
Aligning along the main axis with justify-content:
| Value | Effect |
|---|---|
flex-start | packed at the start |
center | packed in the middle |
flex-end | packed at the end |
space-between | first and last at the edges, equal gaps between |
space-around, space-evenly | space around each item |
Aligning across with align-items: stretch is the default and makes items equal height, and flex-start, center and flex-end do what you would expect. One item can differ using align-self.
So, to centre anything inside a box:
.box { display: flex; justify-content: center; align-items: center; }
Gaps. gap: 12px puts space between items, and nothing before the first or after the last. This is much simpler than margins on each item.
Growing and shrinking. Each item has three settings, usually written together as flex:
flex-grow: how much of any spare space it takes.flex-shrink: how much it gives up when there is not enough room.flex-basis: the size that it starts from.
flex: 1 makes items share the space equally. flex: 0 0 200px makes a fixed column that never changes.
Wrapping. By default items stay on one line and shrink. flex-wrap: wrap lets them flow onto new lines. A common card layout combines it with flex: 1 1 200px, so that cards fill the row and wrap as needed.
The auto margin trick. In a flex container margin-left: auto absorbs all the spare space, which pushes that item to the far end. This is how a logo on the left and links on the right are built.
Order and accessibility. The order property moves items visually. Keyboard focus and screen readers still follow the HTML, so a big difference between the two is confusing. The same is true of row-reverse.
Syntax
.toolbar {
display: flex;
gap: 8px;
justify-content: space-between;
align-items: center;
}
Example
Line by line
display: flexputs all three children in one row.align-items: centerlines them up along the middle of the bar.gapputs equal space between them.- The auto margin on
strongtakes up the spare room, pushing the links to the right.
Expected result
A pale bar with the brand name on the left and two links grouped on the right.
In the real world
Navigation bars, button rows, cards with a footer pinned to the bottom, and form rows are almost always flexbox. It is the most used layout tool in modern CSS.
Common mistakes
- Mixing up the axes, especially after changing to
column. - Expecting grandchildren to be flex items. Only direct children are.
- Using
justify-contentto align vertically in a row. - Using margins for spacing when
gapis simpler.
Best practices
- Learn the axes first, and the property names will follow.
- Use
gapfor spacing. - Keep visual order and source order the same.
- Use flexbox for one direction, and grid for two.
Summary
display: flex arranges direct children along a main axis. justify-content aligns along it, align-items across it, and gap adds space. The flex shorthand controls growth, and flex-wrap allows new lines.
Quick check
Key takeaways
- Flexbox works in one direction at a time.
- justify-content works along the main axis, and align-items across it.
- The flex shorthand controls growing, shrinking and the starting size.
- order changes only what is seen, not the keyboard order.
Practice problems for this lesson
My notes
Write down what you want to remember from this lesson. Notes are saved on this device as you type, and appear on your dashboard.