How it works
The explanation, with examples you can run.
Normal flow
Every element is laid out in flow until you say otherwise. Block boxes (div, p, section, headings) take the full width and stack vertically, with vertical margins that can collapse into each other. Inline content (text, a, span, img) flows in lines and wraps. Headings, paragraphs and lists in a readable column need nothing more than a max-width and sensible margins. position: absolute and fixed take an element out of flow entirely, so nothing else makes room for it.
Flexbox: along one axis
display: flex on a container makes its children flex items laid out along the main axis (a row by default, a column with flex-direction: column). The items' own sizes come first; flex-grow, flex-shrink and flex-basis then decide how leftover space is shared or how overflow is taken back. justify-content places items along the main axis and align-items across it. With flex-wrap: wrap, extra items move to a new line, but each line is laid out on its own, so the items don't form columns.
Good fits: a toolbar, a navigation bar, a button with an icon and a label, a list of tags, centring one thing inside another.
Grid: rows and columns together
display: grid defines tracks on the container with grid-template-columns and grid-template-rows. The fr unit shares out free space, minmax() sets limits, and repeat(auto-fill, ...) creates as many tracks as fit. Items are placed into cells automatically or by line numbers and named areas, and gap spaces the tracks. Because the tracks belong to the container, items in different rows line up. subgrid lets a nested grid reuse its parent's tracks, so the parts of cards in a row can align too.
Good fits: a page frame (header, sidebar, main, footer), a card gallery, a form with aligned labels, anything that looks like a table but isn't tabular data.
Choosing
- Does it need to line up in two directions? Grid.
- Should the content's size decide where things go? Flexbox.
- Is it text and stacked blocks? Leave it in flow.
They nest freely: a grid page whose header is a flex row, whose cards use flow inside. For components that move between narrow and wide slots, container queries (@container) let a component respond to its own width rather than the viewport's.
Check yourself
3 questions. Get them all right to finish this topic.
0 of 3 right so far. Get all three to finish this topic.