—CSS Series · Post 08: CSS Grid
CSS Grid
Layouts in Two Dimensions
Flexbox handles a row or a column. Grid handles both at once. Once you know when to use each, you can build any layout that exists.
💬 "This Layout Doesn't Fit a Row or a Column"
You're building a page layout. There's a header, a sidebar, a main content area, and a footer. Flexbox can handle a row of cards. But this needs rows and columns simultaneously — like a spreadsheet, but for design.
That's what CSS Grid is built for. Grid is a two-dimensional layout system. You define rows and columns, then place items into the resulting cells. Items can span multiple cells. The browser handles the math.
🧠 The Mental Model
Think of Grid as drawing a table on the page and then telling each element which cell to sit in. You define the columns and rows on the container. The children either auto-place themselves (filling cells left to right, top to bottom) or you place them explicitly.
🧱 Grid Basics
grid-template-columns — Defining Your Columns
.container {
display: grid;
/* Three equal columns — fr = fraction of available space */
grid-template-columns: 1fr 1fr 1fr;
/* Shorthand with repeat() */
grid-template-columns: repeat(3, 1fr);
/* Fixed sidebar + flexible main */
grid-template-columns: 240px 1fr;
/* Two equal + one wide */
grid-template-columns: 1fr 2fr 1fr;
}The fr Unit
fr stands for "fraction" — a fraction of the available space. 1fr 1fr 1fr means three columns sharing space equally. 1fr 2fr means the second column gets twice as much space as the first. fr is only available in Grid.
gap — Space Between Cells
.grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 20px; /* same gap between all rows and columns */
row-gap: 24px; /* vertical gaps only */
column-gap: 16px; /* horizontal gaps only */
}Spanning Multiple Cells
Items can span across multiple columns or rows using grid-column and grid-row.
/* Span columns */
.featured { grid-column: span 2; } /* takes up 2 columns */
.full-width{ grid-column: 1 / -1; } /* from col 1 to last col */
/* Span rows */
.sidebar { grid-row: span 3; } /* takes up 3 rows */
/* Explicit placement */
.header {
grid-column: 1 / 4; /* from column line 1 to 4 */
grid-row: 1;
}auto-fill and auto-fit — Responsive Without Media Queries
One of Grid's most powerful features: columns that automatically adjust based on available space, no media queries needed.
.card-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
gap: 20px;
}
/* auto-fill: creates as many columns as fit at minmax minimum
minmax(220px, 1fr): each column is at least 220px, max flexible
Result: as many columns as fit, wraps automatically.
No media queries needed. */🧱 Grid vs Flexbox — When to Use Which
The question isn't which is better. Both are essential and they solve different problems. The rule of thumb: Flexbox for one direction, Grid for two directions. But the real answer is more nuanced.
Use Flexbox when…
- Items flow in a single row or column
- You want items to wrap naturally like text
- Item sizes are content-driven (some bigger, some smaller)
- You're building nav bars, button groups, tag lists
- You need alignment within a component (center icon + text)
Use Grid when…
- You need rows AND columns simultaneously
- You have a defined page or section layout structure
- Items should align across both axes
- You're building dashboards, galleries, page templates
- You need items to span multiple tracks
Flexbox from the content out. Grid from the layout in. Flexbox is great when the content determines the layout. Grid is great when you have a layout structure and you're placing content into it. In practice, most pages use both — Grid for the page template, Flexbox for the components inside it.
Mini Build: Page Template with Grid
Build a classic two-column page layout — fixed sidebar, flexible content — using Grid for the outer template and Flexbox for the inner components.
HTML structure.
<div class="page-layout">
<header class="page-header">Header</header>
<aside class="sidebar">Sidebar</aside>
<main class="content">Main content</main>
<footer class="page-footer">Footer</footer>
</div>Grid CSS. Define named areas for clear, readable layout code.
.page-layout {
display: grid;
grid-template-columns: 240px 1fr;
grid-template-rows: auto 1fr auto;
grid-template-areas:
"header header"
"sidebar content"
"footer footer";
gap: 20px;
min-height: 100vh;
}
.page-header { grid-area: header; }
.sidebar { grid-area: sidebar; }
.content { grid-area: content; }
.page-footer { grid-area: footer; }
/* Responsive: stack to single column on mobile */
@media (max-width: 640px) {
.page-layout {
grid-template-columns: 1fr;
grid-template-areas:
"header"
"content"
"sidebar"
"footer";
}
}Named grid areas let you draw your layout in ASCII art. Each string is a row, each word is a cell. Duplicate names (like "header header") make that element span both columns. Readable, maintainable, and easy to restructure for responsive breakpoints.
💛 You Can Build Any Layout Now
Flexbox and Grid together cover the full landscape of web layout. Flexbox handles the components — navbars, card rows, button groups. Grid handles the structure — page templates, galleries, dashboard layouts.
- display: grid turns a container into a two-dimensional grid
- grid-template-columns defines how many columns and how wide each is
- The fr unit divides available space into proportional fractions
- repeat(auto-fill, minmax(...)) creates responsive columns without media queries
- Items can span multiple cells with grid-column: span N
- Named grid areas let you draw your layout like a diagram
- Flexbox = 1D (row or column). Grid = 2D (rows and columns). Use both.
Next: Responsive Design — media queries, mobile-first thinking, and how to make everything you've built work on any screen size.
When I first learned Grid I thought it was going to replace Flexbox. Why use Flexbox at all if Grid does everything? I spent a whole project trying to use Grid for literally every layout decision, including things like centering an icon next to some text inside a button.
It was... too much. Grid wants structure. It wants rows and columns to exist. Using it inside a button to align two inline elements is using a sledgehammer on a finishing nail.
They each have a domain. Grid gives you the room. Flexbox arranges the furniture inside it. Once I started thinking about it that way — page template in Grid, components in Flexbox — everything got cleaner and faster to write.