CSS Grid is the most powerful layout system in CSS — it gives you control over rows and columns simultaneously. This guide covers everything from basic grids to named areas and responsive patterns. Want to build grids visually? Use the free CSS Grid generator →
CSS Grid gives you control over rows and columns simultaneously. Unlike flexbox (which is one-dimensional), grid lets you place items in a two-dimensional layout with precise control over both axes.
.container {
display: grid;
grid-template-columns: 1fr 2fr 1fr; /* 3 columns */
grid-template-rows: auto 1fr auto; /* 3 rows */
gap: 16px; /* space between cells */
}
/* Fixed widths */
grid-template-columns: 200px 300px 200px;
/* Fractional units (proportional) */
grid-template-columns: 1fr 2fr 1fr; /* 25% / 50% / 25% */
/* Mixed */
grid-template-columns: 250px 1fr; /* fixed sidebar + fluid main */
/* repeat() shorthand */
grid-template-columns: repeat(3, 1fr); /* 3 equal columns */
grid-template-columns: repeat(4, 200px);
/* Auto-fill / auto-fit (responsive without media queries!) */
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
/* Rows */
grid-template-rows: 60px 1fr 40px; /* header, main, footer */
auto-fill creates as many tracks as will fit, leaving empty tracks if there aren't enough items. auto-fit collapses empty tracks so items stretch to fill the space. For most card grids, auto-fit is what you want.gap: 16px; /* same gap for rows and columns */
row-gap: 24px; /* vertical gaps only */
column-gap: 12px; /* horizontal gaps only */
gap: 24px 12px; /* row-gap column-gap */
/* By line numbers (1-indexed) */
.item {
grid-column: 1 / 3; /* spans from line 1 to line 3 (2 columns) */
grid-row: 1 / 2; /* first row */
}
/* Span shorthand */
.item {
grid-column: span 2; /* span 2 columns from wherever it lands */
grid-row: span 3; /* span 3 rows */
}
/* Named lines */
grid-template-columns: [sidebar-start] 250px [sidebar-end main-start] 1fr [main-end];
.sidebar { grid-column: sidebar-start / sidebar-end; }
.main { grid-column: main-start / main-end; }
.container {
display: grid;
grid-template-columns: 250px 1fr;
grid-template-rows: 60px 1fr 40px;
grid-template-areas:
"header header"
"sidebar main"
"footer footer";
gap: 16px;
}
.header { grid-area: header; }
.sidebar { grid-area: sidebar; }
.main { grid-area: main; }
.footer { grid-area: footer; }
This is the most readable way to define page layouts. The string grid literally maps to how the page looks.
A classic page layout using grid-template-areas.
/* Responsive card grid (no media queries) */
.card-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
gap: 24px;
}
/* Holy grail layout */
.page {
display: grid;
grid-template-columns: 250px 1fr 200px;
grid-template-rows: auto 1fr auto;
grid-template-areas:
"header header header"
"nav main aside"
"footer footer footer";
min-height: 100vh;
}
/* Equal-height card row */
.equal-cards {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 16px;
align-items: stretch;
}
/* Masonry-style (CSS only, experimental) */
.masonry {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-template-rows: masonry;
gap: 16px;
}
/* Centered single column (blog layout) */
.blog {
display: grid;
grid-template-columns: minmax(0, 720px);
justify-content: center;
padding: 0 24px;
}
/* Align all items within their cells */
justify-items: start | end | center | stretch; /* horizontal */
align-items: start | end | center | stretch; /* vertical */
place-items: center; /* shorthand: both axes */
/* Align the grid itself within the container */
justify-content: start | end | center | space-between | space-around;
align-content: start | end | center | space-between | space-around;
/* Align a single item */
.item {
justify-self: center;
align-self: end;
}
<div class="grid grid-cols-3 gap-4">
<div class="col-span-2">Wide</div>
<div>Normal</div>
</div>
<!-- Responsive card grid -->
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-6">
<div>Card</div>
<div>Card</div>
<div>Card</div>
</div>
Key utilities: grid, grid-cols-*, grid-rows-*, col-span-*, row-span-*, gap-*, place-items-*, auto-cols-*, auto-rows-*.
minmax(0, 1fr) instead of 1fr to prevent items from expanding beyond their track. 1fr means minmax(auto, 1fr) which won't shrink below content size.max-width: 100%; height: auto; to images inside grid cells.auto-fit instead if you want items to stretch when there are fewer items than tracks.grid-column: 1 / 3 spans columns 1 and 2 (stops before line 3).Set columns, rows, and gaps with sliders — see the grid update in real time and copy the CSS.
Open the Grid Generator →auto-fill creates as many tracks as will fit, leaving empty ones visible. auto-fit collapses empty tracks so items stretch to fill the space. For responsive card grids, auto-fit is usually what you want.
Use grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)). Items will automatically wrap to new rows when they can't fit at the minimum size.
fr stands for "fraction of available space." 1fr 2fr 1fr creates three columns where the middle one is twice as wide as the others.
Use Grid for two-dimensional layouts (page layouts, card grids). Use Flexbox for one-dimensional layouts (navbars, button groups). Combine them: Grid for the outer layout, Flexbox for components inside each cell.