Skip to content

CSS Grid — Two-Dimensional Layout

Flexbox handles one direction at a time. CSS Grid handles both — rows and columns simultaneously. If you have ever set up a layout grid in Figma to keep your columns consistent across breakpoints, CSS Grid is what makes that real in the browser.

The key difference from Flexbox: with Grid, the parent defines the full two-dimensional structure. Children simply slot into it.

display: grid — Activates Grid on the parent container.

grid-template-columns — Defines the column structure. This is the most important Grid property.

grid-template-columns: 200px 1fr 1fr; /* fixed + two flexible columns */
grid-template-columns: repeat(3, 1fr); /* three equal columns */
grid-template-columns: repeat(4, 1fr); /* four equal columns — like a 4-col Figma grid */

fr — the fractional unit — fr means “fraction of the available space”. One 1fr gets one share. Two columns with 1fr 2fr means the second is twice as wide as the first. This is the same idea as Figma’s “fill container” proportional sizing.

gap — Space between rows and columns. You can set both at once (gap: 1rem) or separately (row-gap: 1rem; column-gap: 2rem).

grid-template-areas — Name the regions of your grid and then assign elements to those names. This is incredibly designer-friendly — you are literally drawing the layout.

grid-template-areas:
"header header"
"sidebar main"
"footer footer";

Then on each child: grid-area: header; / grid-area: sidebar; etc.

Below is a classic dashboard grid. Try changing the column count, the fr values, or the gap.

Things to try:

  • Change grid-template-columns: 200px 1fr to 1fr 3fr — the sidebar becomes proportional
  • Change gap to 2rem and watch the breathing room increase
  • Change grid-template-columns to 300px 1fr to widen the sidebar
  • Rearrange grid-template-areas to move the sidebar to the right side

Here is a more common use case — a responsive image gallery using repeat():

Try changing repeat(3, 1fr) to repeat(2, 1fr) or repeat(4, 1fr).

  • Forcing Flexbox to do a two-dimensional job (rows and columns at once) when Grid does it more directly
  • Forgetting that Grid needs both row and column tracks defined up front, in grid-template-columns/grid-template-rows

Designers see “a dashboard/gallery grid,” but developers reach for Grid specifically when the layout is genuinely two-dimensional (rows and columns need to relate to each other), instead of Flexbox, which only really handles one dimension well.

💡 Real-world example

A dashboard of metric cards that needs to align across both rows and columns at once is exactly the two-dimensional problem CSS Grid was designed to solve.

What does `grid-template-columns: repeat(4, 1fr)` create?
What does the `fr` unit represent?
Which property assigns a grid child to a named area defined in grid-template-areas?
What is the main advantage of CSS Grid over Flexbox?