← Back to the Layout Playground
Lesson

Web Layouts, Visually

Layout is how you arrange boxes on a page — headers, sidebars, card grids, sticky bars. This visual lesson builds from normal document flow up through Flexbox, Grid, positioning, and full responsive page layouts, with controls you can click to see each property change live.

Step 1

Normal document flow

Before you add any layout CSS, the browser already arranges elements with normal flow. Two behaviors drive everything:

All of layout is just overriding this default flow when you need rows, columns, or overlap. Most of the time, working with the flow is the simplest, most robust choice.

Step 2

The display property

Every layout decision starts with display — it tells an element how to behave and how to treat its children.

ValueDoes
blockStacks vertically, full width (the default for div).
inlineFlows in a line; width/height ignored.
inline-blockFlows in a line but accepts width/height & padding.
noneRemoves the element entirely (no space kept).
flexMakes children lay out in a row/column — Step 3.
gridMakes children lay out in rows & columns — Step 4.
The two that do the heavy lifting for modern layout are flex and grid. You'll set them on a parent to arrange its children.
Step 3

Flexbox — layout in one direction

Add display: flex to a parent and its children line up in a row. Two properties control alignment: justify-content (along the row) and align-items (across it). Click to see it live:

justify-content: flex-start
1
2
3
.row { display: flex; gap: 10px; justify-content: space-between; }
Reach for Flexbox for navbars, button rows, toolbars, a row of cards, or centering one thing. It's the tool for arranging items along a single line. Add flex-wrap: wrap so items drop to a new line on small screens.
Step 4

CSS Grid — layout in two directions

Grid arranges children into rows and columns at once. Define the columns with grid-template-columns; 1fr means “one share of the free space.” Click a column count:

grid-template-columns: repeat(3, 1fr)
1
2
3
4
5
6
.grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; }
The responsive workhorse: repeat(auto-fit, minmax(200px, 1fr)) fills as many columns as fit and wraps automatically — a fluid card gallery with no media queries. (That's the “auto-fit” button above.)
Step 5

Positioning & layering

Flexbox and Grid arrange things in flow. position lets you take an element out of flow or pin it relative to something.

positionBehaves like
staticDefault — normal flow, ignores top/left.
relativeNormal flow, but nudge-able & an anchor for absolute children.
absoluteOut of flow, placed relative to nearest positioned ancestor.
fixedPinned to the viewport — stays on scroll (sticky headers/FAB).
stickyScrolls normally, then “sticks” at a top offset.

Live: position: sticky — scroll inside this box

I stick to the top while you scroll ↑↓

Scroll this panel. The purple bar stays pinned at the top once it reaches it — the same trick behind sticky section headers and the table-of-contents bar on this very page.

Lorem ipsum content to create scroll height. Sticky positioning needs a top value and a scroll container taller than the element.

Keep scrolling…

…the header never leaves until its parent does.

That's positioning in action.

Use positioning sparingly. It's for overlays, badges, tooltips, and sticky bars — not for general page structure. Reaching for position: absolute to build a layout usually means Flexbox or Grid is the better tool.
Step 6

Building a full page layout

The classic app shell — header, sidebar, main, footer — is a few lines of Grid. This is the “holy grail” layout:

header
sidebar
main content
footer
.app {
  display: grid;
  grid-template-columns: 220px 1fr;   fixed sidebar, fluid main
  grid-template-rows: auto 1fr auto;  header, body, footer
}
header, footer { grid-column: 1 / -1; }   span both columns
A simpler everyday pattern: a centered content column. .container { max-width: 1100px; margin: 0 auto; padding: 0 24px; } keeps text from stretching too wide on big screens.
Step 7

Responsive layouts

Layouts must adapt from phone to desktop. Design mobile-first: simple single-column base styles, then add columns at larger widths with a @media query.

.layout { display: grid; grid-template-columns: 1fr; gap: 20px; }  phone

@media (min-width: 768px) {
  .layout { grid-template-columns: 240px 1fr; }  tablet+: sidebar appears
}
Resize this window — the holy-grail diagram above collapses to one column on narrow screens, and the lesson's grids reflow. Always include <meta name="viewport" content="width=device-width, initial-scale=1.0">.
Step 8

Centering, finally solved

“How do I center a div?” is the oldest CSS question. Modern layout makes it trivial — both axes at once:

.center {
  display: grid;
  place-items: center;   horizontal + vertical, done
}

/* or with flex */
.center { display: flex; justify-content: center; align-items: center; }
To center a fixed-width block horizontally, the old reliable still wins: margin: 0 auto (with a max-width set).
Step 9

Flexbox or Grid? A quick rule

If you're…Use
One lineFlexbox — navbar, button row, tags, centering one item.
Two dimensionsGrid — page shell, card gallery, dashboard, image mosaic.
Content-driven sizingFlexbox — items size to their content, wrap as needed.
Layout-driven sizingGrid — you define the tracks, content fills them.
They combine beautifully: a Grid page shell, with each cell using Flexbox internally for its own row of buttons. You rarely pick just one.
Step 10

Layout checklist

Where next

Keep going