Level 3, Interactive Building, Chapter 8 of 24
CSS Grid & Responsive Design
Why this matters
Every polished website you admire has to work on a phone in someone's pocket, a laptop on a desk, and a huge monitor at a design studio, all with the same HTML and CSS. Flexbox got you comfortable arranging items in a single row or column, but real layouts often need rows and columns working together at the same time, like a photo gallery, a dashboard, or a magazine-style article page.
CSS Grid is the tool made exactly for that job. Once you understand it, you can lay out an entire page structure in a few lines of CSS, then use media queries to reshape that structure as the screen changes, instead of writing a completely different page for every device.
The lesson
From one dimension to two
Flexbox is fundamentally one-dimensional: you pick a direction, row or column, and flex items line up along it. CSS Grid is two-dimensional, meaning you can define rows and columns at the same time and place items into specific cells of that grid. This matters because a lot of real interfaces, like a card gallery with three columns and several rows, are naturally grid-shaped. Trying to force that shape out of flexbox alone usually means fighting with wrapping and widths. Grid lets you describe the shape you want directly, and the browser handles the arithmetic of sizing rows and columns to fit the available space.
1.gallery {2 display: grid;3 grid-template-columns: repeat(3, 1fr);4 gap: 16px;5}Sizing units: fr, auto, and minmax
The fr unit stands for a fraction of the remaining space in the grid container, similar in spirit to flex-grow but applied to grid tracks. grid-template-columns: 1fr 2fr creates two columns where the second is always twice as wide as the first, no matter the container's size. You can mix units too, such as 200px 1fr, which gives a fixed sidebar and a flexible main area. The minmax() function lets a track grow but never shrink below a floor, which is extremely useful for cards that should never get so narrow that text becomes unreadable. Combined with repeat(auto-fit, minmax(200px, 1fr)), you get a gallery that automatically adds or removes columns as the window resizes, with zero media queries required.
1.cards {2 display: grid;3 grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));4 gap: 20px;5}Placing items precisely
Beyond automatic placement, grid lets you put an item in an exact spot using grid-column and grid-row, which accept line numbers or the span keyword. This is how you build layouts like a header that stretches across every column, or a featured card that takes up two rows while smaller cards fill in around it. Because you learned the box model and selectors already, you can think of grid-column and grid-row as extra positioning properties you apply to a grid item the same way you'd apply margin or width, they just describe position within the grid rather than physical pixels.
1.layout {2 display: grid;3 grid-template-columns: repeat(4, 1fr);4 gap: 16px;5}67.layout header {8 grid-column: 1 / -1;9}Responsive design with media queries
Media queries let you apply different CSS rules depending on characteristics of the device, most commonly viewport width. A rule like @media (max-width: 600px) { ... } only applies when the browser window is 600 pixels wide or narrower, which is perfect for switching a three-column grid down to a single column on small screens. The recommended approach is mobile-first: write your base styles for small screens first, then use min-width media queries to add complexity as screens get larger. This tends to produce simpler, more robust CSS than starting from a desktop layout and trying to squash it down.
- Grid handles two-dimensional layout; flexbox handles one-dimensional alignment, and you can use both together.
- fr units divide remaining space proportionally; minmax() sets a safe floor and ceiling for a track's size.
- auto-fit and auto-fill with repeat() create grids that reflow automatically without media queries.
- Media queries let specific rules apply only at certain screen widths, usually written mobile-first.
1.grid {2 display: grid;3 grid-template-columns: 1fr;4 gap: 16px;5}67@media (min-width: 700px) {8 .grid {9 grid-template-columns: repeat(3, 1fr);10 }11}Nesting grid and flexbox together
In practice, most real pages nest the two systems. A page might use grid for the overall structure, header, sidebar, main content, and footer, while each card inside the main content area uses flexbox internally to align an icon next to text or push a button to the bottom. Recognizing which tool fits which job comes with practice: ask whether you're arranging a whole section of the page in rows and columns together (grid) or aligning a handful of items in a single line (flexbox). Neither tool replaces the other, and reaching for both is completely normal.
Try it yourself
Build a responsive photo gallery. Start with a grid of fixed columns, then convert it to use auto-fit and minmax so it reflows on its own, and finally add a media query that changes the gap on small screens.
Chapter boss project
Boss project: Responsive Dashboard Layout
Build a small dashboard page with a header that spans the full width, a sidebar, and a main content area filled with cards. On wide screens, the sidebar sits beside the main content; on narrow screens, the sidebar should move above or below the main content.
The cards inside the main content area should form their own responsive grid that adds or removes columns automatically as the window resizes, without you writing extra media queries for the cards themselves.
Use a mobile-first approach: write the simplest single-column version first, then layer in a min-width media query to unlock the two-column header/sidebar/main layout on larger screens.
- Give the outer layout a grid-template-areas or grid-template-columns definition that changes inside a min-width media query.
- grid-column: 1 / -1 is a quick way to make the header span every column without knowing the exact number of columns.
- For the card grid, try grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)) and resize your preview to watch it reflow.
- Test your smallest layout first before adding the media query, that way you know the base case works on its own.
Level-up checklist
Tick these off once each one is true for you.
