HTML & CSS · Lesson 5 of 5
Grid and Responsive Design
Two-dimensional layouts, media queries and mobile-first CSS.
- Intermediate
- 17 min read
- 3 objectives
Before this lessonLesson 4: Flexbox Layout
What you will learn
- Build a grid layout
- Write media queries
- Use clamp and custom properties
CSS Grid lays out content in rows and columns at the same time. Use Flexbox for one-dimensional alignment and Grid for whole-page or gallery layouts. Combined with media queries, it lets one page adapt to any screen.
Rows and columns at once
Flexbox arranges items in one line. CSS Grid arranges them in a two-dimensional grid of rows and columns, which is what page layouts, galleries and dashboards need. You describe the columns on the parent and the browser places the children into the cells.
.gallery {
display: grid;
grid-template-columns: repeat(3, 1fr); /* three equal columns */
gap: 16px;
}A basic grid
.grid {
display: grid;
grid-template-columns: repeat(3, 1fr); /* three equal columns */
gap: 1rem;
}The fr unit means a fraction of the free space. 1fr 2fr creates a column twice as wide as the first.
Auto-responsive grid, no media query
.gallery {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
gap: 1rem;
}This fits as many columns of at least 220px as the container allows, and grows them evenly. Resize the window and columns appear or disappear by themselves.
Page layout with areas
.page {
display: grid;
grid-template-columns: 220px 1fr;
grid-template-rows: auto 1fr auto;
grid-template-areas:
"header header"
"sidebar main"
"footer footer";
min-height: 100vh;
}
header { grid-area: header; }
aside { grid-area: sidebar; }
main { grid-area: main; }
footer { grid-area: footer; }Mobile-first responsive design
Write styles for the smallest screen first, then use min-width media queries to enhance for larger ones. The result is simpler CSS, and phones download less.
.page { display: block; } /* phone: everything stacked */
@media (min-width: 768px) {
.page {
display: grid;
grid-template-columns: 220px 1fr; /* tablet and up */
}
}Fluid sizing with clamp
h1 { font-size: clamp(1.75rem, 4vw, 3rem); } /* min, preferred, max */
.container { width: min(100% - 2rem, 1100px); margin-inline: auto; }Responsive images
img { max-width: 100%; height: auto; display: block; }Dark mode
:root { --bg: #fff; --text: #111; }
@media (prefers-color-scheme: dark) {
:root { --bg: #0b0b0b; --text: #eaeaea; }
}
body { background: var(--bg); color: var(--text); }What responsive means and why it matters
More than half of web traffic is on phones. A responsive page adapts to the screen: one column on a phone, more on a desktop. Start with the small-screen layout, then add rules for wider screens; this is called mobile-first. Always include this tag in your <head> or phones will zoom out to a fake desktop width:
<meta name="viewport" content="width=device-width, initial-scale=1">A grid that adapts without media queries
.gallery {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
gap: 16px;
}Read it as: "make as many columns as fit, each at least 220px wide, sharing leftover space equally." On a phone you get one column, on a laptop maybe four.
Media queries: change rules at a screen width
.layout {
display: grid;
gap: 24px;
grid-template-columns: 1fr; /* phone: stacked */
}
@media (min-width: 768px) {
.layout {
grid-template-columns: 240px 1fr; /* tablet and up: sidebar + content */
}
}A full page layout with named areas
.page {
display: grid;
grid-template-areas:
"header header"
"sidebar main"
"footer footer";
grid-template-columns: 220px 1fr;
min-height: 100vh;
}
header { grid-area: header; }
aside { grid-area: sidebar; }
main { grid-area: main; }
footer { grid-area: footer; }The grid-template-areas block is literally a picture of the page. Rearranging the layout for a phone is just a matter of writing a different picture inside a media query.
Testing responsiveness
- Open DevTools and toggle the device toolbar to preview phone and tablet sizes.
- Drag the window narrower and watch for text that overflows or buttons too small to tap.
- Aim for tap targets of at least 44 by 44 pixels and body text of at least 16px.
Key takeaways
- Grid lays out rows and columns together; Flexbox handles a single row or column.
repeat(auto-fit, minmax(220px, 1fr))gives a responsive gallery with no media queries.- Design mobile-first and add
@media (min-width: ...)rules for larger screens. - Always include the viewport meta tag.
// Write your solution here
