Let’s build a small page that uses most of the chapter: mobile-first, fluid type, a card grid and one media query.
<style>
*, *::before, *::after { box-sizing: border-box; }
body { margin: 0; font-family: system-ui, sans-serif; line-height: 1.5; color: #1c1b1f; }
/* Header */
.site-header { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 8px; padding: 12px 16px; background: #1a5276; color: #fff; }
.site-header a { color: #fff; text-decoration: none; margin-left: 12px; }
/* Hero */
.hero { padding: 32px 16px; background: #fdf2e9; text-align: center; }
.hero h1 { margin: 0 0 8px; font-size: clamp(1.6rem, 6vw, 2.6rem); line-height: 1.15; }
.btn { display: inline-block; padding: 10px 20px; background: #d94a00; color: #fff; text-decoration: none; border-radius: 6px; }
/* Card grid: one column by default */
.cards { display: grid; gap: 12px; padding: 16px; }
.card { border: 1px solid #e6ddd7; border-radius: 8px; padding: 14px; }
/* Footer */
footer { padding: 16px; background: #eee; text-align: center; font-size: 14px; }
/* More room: two columns */
@media (min-width: 420px) {
.cards { grid-template-columns: 1fr 1fr; }
}
</style>
<header class="site-header">
<strong>Juniper Books</strong>
<nav><a href="#">Shop</a><a href="#">Journal</a></nav>
</header>
<section class="hero">
<h1>Books for slow afternoons</h1>
<p>Hand-picked fiction, poetry and travel writing.</p>
<a class="btn" href="#">Browse the shop</a>
</section>
<section class="cards">
<article class="card"><h2>Fiction</h2><p>Novels and short stories.</p></article>
<article class="card"><h2>Poetry</h2><p>New and classic voices.</p></article>
<article class="card"><h2>Travel</h2><p>Places worth reading about.</p></article>
<article class="card"><h2>Cooking</h2><p>Recipes with a story.</p></article>
</section>
<footer>© Juniper Books</footer>
What to notice
- Mobile first. Everything outside the media query is the small-screen layout.
- One media query. It only changes the card grid from one to two columns.
- No fixed widths. The page flows to fit.
- Fluid hero title with
clamp(). - The header wraps thanks to
flex-wrap, so it will not overflow on narrow screens.
Make it yours
- Change the breakpoint from
420pxto300pxor600pxand see when the cards change. - Make the grid three columns above
700px. - Add a
max-widthcontainer so the cards do not stretch across a very wide screen.
Exercise: a third breakpoint
Add a media query that shows the cards in four columns at 800px and wider. The first four cards should fit in one row.
Show a possible solution
@media (min-width: 800px) {
.cards { grid-template-columns: repeat(4, 1fr); }
}
Place it after the 420px query, so it overrides it.