Layout with HTML & CSS
HTML describes the content; CSS arranges it on screen. This lesson shows how a well-structured HTML page becomes a classic layout — header, navigation, content, sidebar, footer — using CSS Grid and Flexbox, and why good HTML structure makes layout easy.
Start with meaningful HTML
Write the HTML in the order it should be read, using semantic elements. Without any CSS, this already produces a sensible, accessible single-column page:
<body> <header>…logo and title…</header> <nav>…links…</nav> <main>…main content…</main> <aside>…sidebar…</aside> <footer>…footer…</footer> </body>
A page layout with CSS Grid
grid-template-areas draws the layout as a little text picture. On narrow screens, a media query stacks everything into one column — the HTML doesn't change at all.
Flexbox for rows of items
Flexbox is ideal for laying out items in a single row or column — navigation bars, toolbars, card rows:
A responsive card grid
With repeat(auto-fill, minmax(140px, 1fr)), the grid fits as many 140px-plus columns as it can and wraps the rest — responsive without a single media query.
Source order matters
CSS can visually move things anywhere, but screen readers and keyboard users follow the HTML order. If CSS shows the sidebar first while the HTML lists it last, keyboard focus will jump around confusingly. Keep the visual order and the HTML order the same wherever possible.
Layout techniques compared
| Technique | Use for |
|---|---|
| Normal flow | Most content — paragraphs and blocks stack naturally |
| Flexbox | One-dimensional rows or columns: navbars, buttons, centring |
| Grid | Two-dimensional layouts: whole pages, galleries, dashboards |
| Positioning | Overlays, sticky headers, badges on images |
| Tables | Only for tabular data — never for layout |
| Floats | Wrapping text around an image (no longer used for page layout) |
The CSS course covers each of these in depth.
Try it yourself
Change 1fr 180px to 180px 1fr in the grid example above to put the sidebar on the left — then notice that the HTML order didn't change. Or experiment with this holy-grail layout: