Introduction to CSS Grid — Two-Dimensional Layout
You have spent this module arranging elements in a single direction — rows of cards, horizontal navigation bars, vertically stacked content. CSS Grid solves a different problem: placing elements in rows and columns at the same time.
Flexbox and Grid are not rivals. Most real pages use both — Grid for the overall structure, Flexbox for components inside the grid cells.
Flexbox vs Grid — the mental model
Section titled “Flexbox vs Grid — the mental model”Flexbox thinks about content. You define a container, and items decide how much space they take based on their content and flex values. The layout adapts to the items.
Grid thinks about structure first. You define the column and row structure on the container, then items are placed into that structure. The layout drives the content.
Flexbox: [ item ][ item ][ item ] ← items determine spacingGrid: [ col ][ col ][ col ] ← columns defined firstThe analogy: Flexbox is like arranging books on a shelf — the books determine how the shelf fills. Grid is like designing a floor plan — you define the rooms first, then place the furniture.
Use Flexbox when the content should drive the layout. Use Grid when the layout should drive the content.
display: grid
Section titled “display: grid”Activating Grid requires one property on the container:
.team-grid { display: grid;}Like display: flex, this affects only direct children — they become grid items. Deeper descendants are unaffected.
Without grid-template-columns, the browser creates a single-column grid and items stack vertically — identical to normal flow. Grid becomes useful once you define a column structure.
grid-template-columns
Section titled “grid-template-columns”This property defines the column structure. Each value you provide creates a column:
/* Two equal columns */.about-story-inner { display: grid; grid-template-columns: 1fr 1fr;}
/* Fixed sidebar, flexible content area */.sidebar-layout { display: grid; grid-template-columns: 280px 1fr;}
/* Three equal columns */.team-grid { display: grid; grid-template-columns: 1fr 1fr 1fr;}The fr unit
Section titled “The fr unit”fr stands for fractional unit — a share of the available space after fixed-width columns are subtracted.
grid-template-columns: 1fr 2fr;/* Second column is twice as wide as the first. In a 900px container: first = 300px, second = 600px */fr works like flex-grow in Flexbox — it distributes remaining space proportionally.
repeat()
Section titled “repeat()”Instead of writing 1fr 1fr 1fr, use repeat(count, value):
grid-template-columns: repeat(3, 1fr); /* same as 1fr 1fr 1fr */grid-template-columns: repeat(4, 200px); /* four 200px columns */gap in Grid
Section titled “gap in Grid”The gap property works in Grid exactly as it does in Flexbox — space between items, no outer margins:
.team-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 2rem;}Control rows and columns independently:
gap: 1.5rem 3rem; /* row-gap: 1.5rem, column-gap: 3rem */The responsive grid pattern — auto-fill and minmax()
Section titled “The responsive grid pattern — auto-fill and minmax()”This is Grid’s most practical beginner technique — a multi-column grid that reflows at all viewport widths without any media query:
.team-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: 2rem;}Breaking it down:
auto-fill— create as many columns as will fit in the container widthminmax(240px, 1fr)— each column is at least 240px wide, growing up to 1fr of available space
At 900px: three columns. At 550px: two columns. At 300px: one column. No @media required.
This achieves a similar result to the Flexbox flex: 1 1 280px; flex-wrap: wrap pattern from Lesson 05, but Grid distributes columns more precisely — items always fill the row without a single narrow orphan at the end.
Spanning multiple columns
Section titled “Spanning multiple columns”A grid item can span more than one column using grid-column: span N:
.blog-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 1.5rem;}
.post-card:first-child { grid-column: span 2; /* featured post takes two of the three columns */}Useful for a featured item that should stand out from the rest of the grid. The remaining items fill in after it automatically.
grid-template-rows
Section titled “grid-template-rows”You can define row heights, but in most cases you do not need to — the browser creates implicit rows automatically based on content height. Leave grid-template-rows undefined unless you have a specific reason to control vertical sizing.
When to reach for Grid vs Flexbox
Section titled “When to reach for Grid vs Flexbox”| Situation | Reach for |
|---|---|
| Horizontal navigation bar | Flexbox |
| Centering a single item | Flexbox |
| Label stacked above input | Flexbox |
| Card row that wraps | Either |
| Image + text side by side | Grid |
| Team or photo gallery | Grid |
| Page-level structure (header / main / sidebar) | Grid |
| Dashboard with defined rows and columns | Grid |
If you are thinking in one direction — “I want items in a row” or “I want items in a column” — reach for Flexbox. If you are thinking in two directions simultaneously — “I want a three-column grid where items also have defined row heights” — reach for Grid.
Exercise
Section titled “Exercise”Apply CSS Grid to the STO about page:
- Add a two-column story layout in
style.css:
.about-story-inner { display: grid; grid-template-columns: 1fr 1fr; gap: 3rem; align-items: center;}Open about.html on a wide screen — the image placeholder and text block should sit side by side in equal columns.
- Apply the responsive team grid:
.team-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: 2rem;}Resize the browser slowly — watch the guide cards reflow from three columns to two to one with no media query.
-
In DevTools, click the
.team-gridelement. A small grid badge appears next to it in the Elements panel — click it to toggle the Grid overlay. The overlay draws column and row lines directly on the page, showing you exactly how the grid is calculated. -
Experiment: change
grid-template-columns: 1fr 1frin the story section togrid-template-columns: 1fr 2fr. The text column should now be twice as wide as the image column.
- Flexbox is one-dimensional (a row or a column); Grid is two-dimensional (rows and columns simultaneously). Use both — they are complementary.
display: gridactivates Grid on a container; direct children become grid items.grid-template-columnsdefines the column structure. Thefrunit distributes space proportionally:1fr 2frmakes the second column twice as wide as the first.repeat(count, value)shorthand:repeat(3, 1fr)is equivalent to1fr 1fr 1fr.gapadds space between grid items without outer margins.repeat(auto-fill, minmax(240px, 1fr))creates a responsive grid that reflows at all viewport widths without media queries.grid-column: span 2makes an item span two columns.
Module 06 covers Styling Forms — applying everything you know about selectors, the box model, Flexbox, and transitions to build a complete, accessible contact form.