Activating CSS Grid
.container { display: grid; }
/* or: */
.container { display: inline-grid; } /* grid that flows inline */
Direct children of a grid container automatically become grid items. Without defining columns/rows, items stack vertically in a single column (like block display).
grid-template-columns & grid-template-rows
Define the grid's track structure. Each value in the list defines one column (or row) and its size.
/* 3 equal columns of 200px each */
grid-template-columns: 200px 200px 200px;
/* 3 columns with different sizes */
grid-template-columns: 260px 1fr 1fr; /* sidebar + 2 equal mains */
/* 2 rows of specific heights */
grid-template-rows: 64px 1fr; /* fixed header + flexible content */
The fr Unit – Fractional Space
fr (fraction) represents a fraction of the available free space in the grid container. It's the most important CSS Grid unit.
/* 3 equal columns — each gets 1/3 of available width */
grid-template-columns: 1fr 1fr 1fr;
/* Unequal — first gets 1/4, second 3/4 */
grid-template-columns: 1fr 3fr;
/* Mix px and fr — px columns are sized first, fr gets the rest */
grid-template-columns: 260px 1fr; /* fixed sidebar + flexible main */
grid-template-columns: 260px 1fr 300px; /* sidebar + main + ads */
repeat() – Shorthand for Repeated Tracks
/* Verbose */
grid-template-columns: 1fr 1fr 1fr 1fr;
/* Same with repeat(count, size) */
grid-template-columns: repeat(4, 1fr);
/* Repeat a pattern */
grid-template-columns: repeat(3, 1fr 2fr);
/* = 1fr 2fr 1fr 2fr 1fr 2fr */
/* auto-fill — create as many columns as fit */
grid-template-columns: repeat(auto-fill, 200px);
/* auto-fit — same but collapses empty tracks */
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
minmax() – Flexible Track Sizing
minmax(min, max) defines a track that is at least min wide and at most max wide.
/* Column that's at least 200px but can grow to fill space */
grid-template-columns: repeat(3, minmax(200px, 1fr));
/* The responsive card grid — the most used Grid pattern */
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
/* Creates as many 280px+ columns as fit. When space is tight:
fewer columns. When space is wide: more columns. Zero media queries! */
gap – Spacing Between Tracks
gap: 24px; /* equal row and column gap */
gap: 16px 24px; /* row-gap: 16px, column-gap: 24px */
row-gap: 16px;
column-gap: 24px;
Placing Items – grid-column & grid-row
Grid items can be placed on specific lines. Grid lines are numbered from 1 (or -1 from the end).
/* grid-column: start / end */
.wide-item {
grid-column: 1 / 3; /* spans from line 1 to line 3 (2 columns) */
}
/* span keyword — span N tracks */
.wide-item {
grid-column: span 2; /* spans 2 columns from wherever it auto-places */
}
/* grid-row: start / end */
.tall-item {
grid-row: 1 / 3; /* spans 2 rows */
}
/* From the end — -1 = last line */
.full-width {
grid-column: 1 / -1; /* spans all columns regardless of how many */
}
Named Grid Areas
The most readable way to define complex layouts. Name areas in the template, then assign items to areas.
.page {
display: grid;
grid-template-areas:
"header header header"
"sidebar main main"
"footer footer footer";
grid-template-columns: 260px 1fr 1fr;
grid-template-rows: 64px 1fr 60px;
min-height: 100vh;
gap: 0;
}
.site-header { grid-area: header; }
.sidebar { grid-area: sidebar; }
.main-content { grid-area: main; }
.site-footer { grid-area: footer; }
/* Use . (dot) for an empty cell */
grid-template-areas:
"header header"
"sidebar main"
". footer";
Alignment in Grid
/* Align ALL items within their cells */
align-items: start | end | center | stretch; /* cross axis (vertical) */
justify-items: start | end | center | stretch; /* main axis (horizontal) */
place-items: center; /* shorthand: align + justify */
/* Align individual item within its cell */
align-self: center; /* vertical */
justify-self: center; /* horizontal */
place-self: center; /* shorthand */
/* Align entire grid inside container (when grid is smaller than container) */
align-content: start | end | center | space-between | space-around;
justify-content: center;
Real-World Grid Patterns
/* 1. Responsive card grid — no media queries needed */
.cards {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
gap: 24px;
}
/* 2. Full-page layout */
.app {
display: grid;
grid-template-rows: 60px 1fr 48px;
grid-template-areas: "header" "main" "footer";
min-height: 100vh;
}
/* 3. Image masonry-style gallery */
.gallery {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-auto-rows: 200px;
gap: 12px;
}
.gallery .featured {
grid-column: span 2;
grid-row: span 2;
}
/* 4. 12-column layout (like Bootstrap) */
.grid-12 {
display: grid;
grid-template-columns: repeat(12, 1fr);
gap: 16px;
}
.col-6 { grid-column: span 6; } /* half width */
.col-4 { grid-column: span 4; } /* one third */
.col-3 { grid-column: span 3; } /* one quarter */
/* 5. CSS Grid centering (alternative to flexbox) */
.center {
display: grid;
place-items: center;
}
📋 Summary
- display: grid — activates Grid on the container.
- grid-template-columns / rows — define the track structure.
- fr — fractional unit.
1fr= equal share of available space. - repeat(count, size) — shorthand for repeated tracks.
- minmax(min, max) — flexible track that stays between min and max.
- repeat(auto-fit, minmax(280px, 1fr)) — the responsive card grid pattern.
- grid-column/row: start / end — place items on specific lines.
span Nto span N tracks. - grid-column: 1 / -1 — always spans all columns.
- grid-template-areas + grid-area — named layout regions, most readable approach.
- gap — spacing between rows and columns.
- place-items: center — center all items in cells.
Frequently Asked Questions
Both create as many columns as fit the container. The difference appears when there are fewer items than columns: auto-fill creates empty tracks (the grid has empty columns), auto-fit collapses empty tracks (the existing items stretch to fill the space). For most card grids you want auto-fit so items expand when there are fewer of them. Use auto-fill when you want a fixed grid structure regardless of item count.
Grid excels at two-dimensional layouts — when you need to control both rows and columns simultaneously, or when the parent controls the layout (known size containers). Flexbox excels at one-dimensional layouts — rows of items, vertical stacking, when the content controls the size (unknown sizes). In practice: Grid for page-level layout, Grid for galleries and card grids, Flexbox for navigation bars, button groups, form rows, and component internals. They're complementary — use both in the same project.
The magic one-liner: grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)). This creates as many columns as fit, where each is at least 280px wide and at most 1fr (fills available space). On a narrow viewport: 1 column. On a medium viewport: 2 columns. On a wide viewport: 3+ columns. No media queries needed. Adjust 280px to suit your content — it's the breakpoint where columns collapse.
grid-area has two uses: (1) Assign a named area to a grid item, where the name corresponds to a region defined in grid-template-areas — e.g., grid-area: sidebar. (2) Shorthand for row-start / column-start / row-end / column-end — e.g., grid-area: 1 / 1 / 3 / 4. The named approach is much more readable and is preferred for complex layouts.