CSS Grid
CSS Grid gives you true two-dimensional control over layouts — place things in rows AND columns at the same time, no more nesting hacks required.
Imagine you are designing a magazine spread. You want a big photo in the top-left corner, a headline stretching across the top, body text on the right, and a caption in the bottom-left. With older CSS you would fight floats and nested divs all day. CSS Grid was built to solve this problem.
Grid gives you a real coordinate system: rows and columns that you define, and items you can place precisely — or let the browser arrange automatically. It is the most powerful layout tool CSS has ever had.
Think of it like a spreadsheet
A spreadsheet has columns (A, B, C…) and rows (1, 2, 3…). Any cell — or a merged group of cells — can hold content. CSS Grid works the same way. You define how many columns and rows exist, and each element snaps into a cell or spans across several cells. The browser handles the math; you just say where things go.
#Activating the Grid and Defining Columns
Grid is activated on the parent container with display: grid. Its children automatically become grid items. Use grid-template-columns to describe the columns — each space-separated value defines one column's width.
Pixel widths are rigid and can overflow small screens, so Grid introduces the `fr` unit (short for fraction). 1fr means "one share of the available space." Think of slicing a pizza: 1fr 1fr 1fr is three equal slices; 2fr 1fr gives one slice twice as wide as the other.
The gap property adds consistent gutters between all rows and columns at once, never at the outer edges. And repeat(n, size) saves repetition — repeat(4, 1fr) is identical to 1fr 1fr 1fr 1fr.
.three-col {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
gap: 24px;
}
.sidebar-layout {
display: grid;
grid-template-columns: 1fr 3fr; /* sidebar : main = 1 : 3 */
gap: 24px;
}
.gallery {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 16px;
}The one-liner responsive grid
repeat(auto-fill, minmax(200px, 1fr)) is the most practical single line in all of CSS Grid: - `auto-fill` — create as many columns as fit in the container - `minmax(200px, 1fr)` — each column is at least 200 px wide and can grow to fill space
On a wide screen you get 4 or 5 columns; on a phone you get 1. No media queries at all. This one line handles the majority of card-grid layouts in real projects.
#Explicit Rows and Placing Items Precisely
grid-template-rows works exactly like grid-template-columns but vertically. Most of the time you can leave rows implicit — Grid creates them automatically. Define them explicitly only when you need fixed heights like a header or footer band.
To place an item in a specific cell — or span it across several — use grid-column and grid-row. Grid counts the invisible lines between cells, starting at 1. A three-column grid has four column lines (1 through 4). The special value -1 always means the last line, so grid-column: 1 / -1 spans all columns without hard-coding the count.
.page {
display: grid;
grid-template-columns: 240px 1fr;
grid-template-rows: 64px 1fr 48px; /* header, content, footer */
min-height: 100vh;
gap: 16px;
}
/* Hero banner spans every column */
.hero {
grid-column: 1 / -1;
}
/* Starts at column 2, spans two columns */
.wide-card {
grid-column: 2 / span 2;
}Line numbers start at 1, not 0
This catches almost everyone coming from zero-indexed languages. A grid with 3 columns has 4 column lines (1 through 4). grid-column: 1 / 2 places an item in column one only. grid-column: 1 / 4 spans all three columns — same as writing 1 / -1 on a three-column grid.
#Grid vs. Flexbox — When to Use Which
Grid and Flexbox are complementary, not competitors:
- Flexbox — items in one direction (a row of nav links, a stack of cards, a button group). The container adapts to fit the items.
- Grid — a two-dimensional structure you define first, then content fills it (a dashboard, a photo gallery, a full-page layout).
In real projects you will nest them constantly: Grid handles the overall page structure, Flexbox aligns items inside each grid cell.
/* Grid for the overall page structure */
.page {
display: grid;
grid-template-columns: 240px 1fr;
grid-template-rows: 64px 1fr;
min-height: 100vh;
}
/* Flexbox inside the header cell */
.header {
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 24px;
}You want a photo gallery where as many columns as possible fit, each at least 180 px wide, growing to fill remaining space — with no media queries. Which value achieves this?
Key takeaways
- display: grid on the parent turns its children into grid items — columns and rows are defined on the container, not the items.
- The fr unit distributes available space proportionally, making layouts far more flexible than fixed pixel or percentage widths.
- repeat(auto-fill, minmax(min, 1fr)) is the most practical one-liner in CSS Grid — a fully responsive column layout with zero media queries.
- Use grid-column and grid-row to place items across multiple cells; line numbers start at 1, and -1 always means the last line.
- Grid owns two-dimensional layout; Flexbox owns one-dimensional alignment — use them together, Grid for page structure and Flexbox inside each cell.
The container is 320px wide with no gap. What visual result does this grid produce for its two child items?
.sidebar-layout {
display: grid;
grid-template-columns: 1fr 3fr;
}Complete this one line so the gallery packs in as many columns as fit, each at least 200px wide but free to grow to fill the row — with zero media queries.
.gallery { display: grid; grid-template-columns: repeat(, minmax(200px, 1fr)); gap: 16px; }
This code has a bug — the developer wanted three equal columns but got a single stacked column instead. What's wrong?
.three-col {
display: grid;
grid-columns: 1fr 1fr 1fr;
gap: 24px;
}On a 3-column grid, order these facts about column LINES from the FIRST line (top) to the LAST line (bottom), matching how the lesson numbers them.
Line 2 — between column one and column two
Line 4 — the right edge, which -1 also refers to
Line 3 — between column two and column three
Line 1 — the left edge, where the first column starts
Build a classic blog-page layout using CSS Grid. The page should have a full-width header, a wide main content area, a narrower sidebar, and a full-width footer. Use fr units for columns (main gets 3 shares, sidebar gets 1 share), add a gap between areas, and make the header and footer span all columns.
Try it live — edit the code and hit Run to see it rendered: