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.
The essential properties
Section titled “The essential properties”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.
Edit a dashboard layout
Section titled “Edit a dashboard layout”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 1frto1fr 3fr— the sidebar becomes proportional - Change
gapto2remand watch the breathing room increase - Change
grid-template-columnsto300px 1frto widen the sidebar - Rearrange
grid-template-areasto move the sidebar to the right side
A photo gallery with repeat()
Section titled “A photo gallery with repeat()”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).