Table of Contents
- Understanding CSS Grid Basics
- Core Grid Terminology
- Setting Up a Grid Container
- Defining Grid Tracks (Rows & Columns)
- Grid Lines and Numbering
- Placing Items on the Grid
- Spanning Grid Items
- Grid Template Areas: Visual Layouts
- Auto-Fit & Auto-Fill: Responsive Columns
- Alignment in CSS Grid
- Responsive Grid Design with Media Queries
- Advanced Grid Techniques
- Common Pitfalls & Solutions
- Conclusion
- References
1. Understanding CSS Grid Basics
At its core, CSS Grid is a layout model designed to handle both rows and columns simultaneously. It works by defining a grid container (the parent element) and grid items (its direct children). The container acts as a “canvas,” and items are placed within the grid’s rows and columns.
Key Advantage Over Flexbox:
Flexbox is one-dimensional (it arranges items in a single row or column), making it ideal for component-level layouts (e.g., navigation bars, card content). Grid, by contrast, excels at page-level layouts (e.g., arranging headers, sidebars, main content, and footers in a 2D grid).
2. Core Grid Terminology
Before diving into code, let’s define key Grid terms to avoid confusion:
| Term | Definition |
|---|---|
| Grid Container | The parent element with display: grid; it defines the grid context. |
| Grid Items | Direct children of the grid container; these are laid out on the grid. |
| Grid Tracks | The rows and columns of the grid (e.g., a grid with 3 columns has 3 column tracks). |
| Grid Lines | The dividing lines around tracks (numbered starting at 1). For 3 columns, there are 4 vertical grid lines. |
| Grid Cell | The intersection of a row and column (like a cell in a table). |
| Grid Area | A rectangular region of the grid spanning multiple cells. |
| Gaps | The space between grid tracks (rows/columns), set with gap (shorthand for row-gap and column-gap). |
3. Setting Up a Grid Container
To start using Grid, first define a grid container. Let’s use a simple HTML structure with a container and 6 child items:
<div class="grid-container">
<div class="grid-item">1</div>
<div class="grid-item">2</div>
<div class="grid-item">3</div>
<div class="grid-item">4</div>
<div class="grid-item">5</div>
<div class="grid-item">6</div>
</div>
To turn .grid-container into a grid, add display: grid in CSS:
.grid-container {
display: grid; /* Enables Grid layout */
gap: 1rem; /* Adds 1rem space between items */
}
Initial Behavior:
By default, a grid container has 1 column track (so items stack vertically) and as many row tracks as needed to fit all items. To see a multi-column layout, we need to define columns explicitly.
4. Defining Grid Tracks (Rows & Columns)
Grid tracks (rows and columns) are defined with:
grid-template-columns: Defines column tracks.grid-template-rows: Defines row tracks.
Units for Tracks:
Use these units to size tracks:
fr: Fractional unit (distributes available space proportionally).px/em/rem: Fixed units.%: Percentage of the container’s size.auto: Takes up space based on content.
Example 1: Fixed Columns
Create 3 equal-width columns (200px each):
.grid-container {
display: grid;
grid-template-columns: 200px 200px 200px; /* 3 columns, 200px each */
gap: 1rem;
}
Example 2: Flexible Columns with fr
Use fr to divide space proportionally. Here, the first and third columns take 1 part each, and the middle takes 2 parts:
.grid-container {
display: grid;
grid-template-columns: 1fr 2fr 1fr; /* Total: 4fr → 1/4, 2/4, 1/4 */
gap: 1rem;
}
Example 3: Mixed Units
Combine fixed and flexible units. The first column is 150px, the second adapts to content (auto), and the third takes remaining space (1fr):
.grid-container {
display: grid;
grid-template-columns: 150px auto 1fr;
gap: 1rem;
}
Example 4: Repeating Tracks
Use repeat() to avoid repetition. Create 4 columns, each 1fr:
.grid-container {
display: grid;
grid-template-columns: repeat(4, 1fr); /* Shorthand for 1fr 1fr 1fr 1fr */
gap: 1rem;
}
5. Grid Lines and Numbering
Grid lines are the invisible lines that separate tracks. For a grid with grid-template-columns: 1fr 1fr 1fr (3 columns), there are 4 vertical grid lines (numbered 1 to 4). Similarly, 2 rows have 3 horizontal grid lines.

Source: MDN Web Docs
Grid lines are critical for placing items (covered next).
6. Placing Items on the Grid
By default, grid items auto-place in order (left-to-right, top-to-bottom). To manually position items, use these properties on grid items:
| Property | Description |
|---|---|
grid-column-start | Starting vertical grid line (e.g., 1). |
grid-column-end | Ending vertical grid line (e.g., 3). |
grid-row-start | Starting horizontal grid line (e.g., 1). |
grid-row-end | Ending horizontal grid line (e.g., 2). |
Shorthand Properties:
grid-column: Shorthand forgrid-column-start/grid-column-end(e.g.,1 / 3).grid-row: Shorthand forgrid-row-start/grid-row-end(e.g.,1 / 2).
Example: Span Columns with span
Use span to define how many tracks an item should span (instead of referencing line numbers).
.grid-item:nth-child(2) {
grid-column: span 2; /* Spans 2 columns */
}
This item will start at its default position and span 2 columns.
7. Spanning Grid Items
Spanning is useful for creating classic layouts (e.g., headers spanning all columns, sidebars spanning multiple rows).
Example: Page Layout with Spanning
Let’s build a layout with:
- Header (spans all columns).
- Sidebar (spans 2 rows).
- Main content (spans 2 rows).
- Footer (spans all columns).
HTML:
<div class="page-layout">
<header>Header</header>
<aside>Sidebar</aside>
<main>Main Content</main>
<footer>Footer</footer>
</div>
CSS:
.page-layout {
display: grid;
grid-template-columns: 1fr 3fr; /* Sidebar (1fr) + Main (3fr) */
grid-template-rows: auto 1fr auto; /* Header (auto) + Content (1fr) + Footer (auto) */
gap: 1rem;
min-height: 100vh; /* Full viewport height */
}
header, footer {
grid-column: 1 / -1; /* Span from first to last column line (-1 = last line) */
}
aside {
grid-row: 2 / 3; /* Spans row 2 */
}
main {
grid-row: 2 / 3; /* Spans row 2 */
}
Here, grid-column: 1 / -1 ensures the header and footer span all columns (-1 refers to the last grid line, making it responsive).
8. Grid Template Areas: Visual Layouts
grid-template-areas lets you define layouts visually using named regions (e.g., “header”, “sidebar”). It’s one of Grid’s most intuitive features.
How It Works:
- Name grid items with
grid-area: [name](e.g.,header { grid-area: header }). - Define the layout in
grid-template-areas(each string = 1 row; names = columns).
Example: Same Page Layout with grid-template-areas
.page-layout {
display: grid;
grid-template-columns: 1fr 3fr;
grid-template-rows: auto 1fr auto;
grid-template-areas:
"header header" /* Row 1: header spans both columns */
"sidebar main" /* Row 2: sidebar (col1), main (col2) */
"footer footer"; /* Row 3: footer spans both columns */
gap: 1rem;
min-height: 100vh;
}
header { grid-area: header; }
aside { grid-area: sidebar; }
main { grid-area: main; }
footer { grid-area: footer; }
This is far more readable than line-based placement! Use . to represent empty cells (e.g., grid-template-areas: "header ." "sidebar main").
9. Auto-Fit & Auto-Fill: Responsive Columns
For responsive grids (e.g., card grids that adjust column count based on screen size), use repeat(auto-fit, minmax(min-size, 1fr)).
auto-fit vs. auto-fill:
auto-fill: Creates as many tracks as possible to fit the container (even if empty).auto-fit: Collapses empty tracks, expanding filled tracks to fill space.
Example: Responsive Card Grid
Create a grid that shows 1 column on mobile, 2 on tablets, and 3+ on desktops:
.card-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); /* Min 250px per card */
gap: 1rem;
}
- On small screens: 1 column (250px wide).
- On medium screens: 2 columns (each ~250px).
- On large screens: 3+ columns (each ~250px).
10. Alignment in CSS Grid
Grid provides powerful alignment controls for both the container (all items) and individual items.
Container-Level Alignment:
Aligns the entire grid within the container (useful if the grid is smaller than the container).
| Property | Description |
|---|---|
justify-content | Aligns grid along the inline (row) axis (left/right in LTR languages). |
align-content | Aligns grid along the block (column) axis (top/bottom). |
place-content | Shorthand for align-content / justify-content (e.g., center center). |
Item-Level Alignment:
Aligns items inside their grid cells.
| Property | Description |
|---|---|
justify-items | Aligns all items along the inline (row) axis (e.g., center). |
align-items | Aligns all items along the block (column) axis (e.g., center). |
place-items | Shorthand for align-items / justify-items (e.g., center center). |
Individual Item Alignment:
Override alignment for a single item with:
justify-self: Inline axis alignment for one item.align-self: Block axis alignment for one item.
Example: Center Items in a Grid
Center all items inside their cells:
.grid-container {
display: grid;
grid-template-columns: repeat(3, 1fr);
align-items: center; /* Vertically center items */
justify-items: center; /* Horizontally center items */
gap: 1rem;
height: 400px; /* Container has fixed height */
}
11. Responsive Grid Design with Media Queries
Combine Grid with media queries to adapt layouts to different screen sizes.
Example: Mobile-First Layout
Start with a single column for mobile, then add columns for larger screens:
.responsive-layout {
display: grid;
grid-template-columns: 1fr; /* Default: 1 column */
gap: 1rem;
}
/* Tablet: 2 columns */
@media (min-width: 768px) {
.responsive-layout {
grid-template-columns: 1fr 1fr;
}
}
/* Desktop: 3 columns */
@media (min-width: 1024px) {
.responsive-layout {
grid-template-columns: 1fr 1fr 1fr;
}
}
12. Advanced Grid Techniques
Nested Grids
Grid containers can be nested inside grid items to create complex layouts.
<div class="outer-grid">
<div class="inner-grid"> <!-- This is a grid item AND a grid container -->
<div>Item 1</div>
<div>Item 2</div>
</div>
</div>
.outer-grid {
display: grid;
grid-template-columns: 2fr 1fr;
}
.inner-grid {
display: grid;
grid-template-columns: repeat(2, 1fr); /* Inner grid with 2 columns */
}
grid-auto-flow: dense
Automatically fills gaps in the grid caused by spanning items (prevents empty spaces).
.grid-container {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-auto-flow: dense; /* Fills gaps */
}
13. Common Pitfalls & Solutions
| Pitfall | Solution |
|---|---|
| Items not laying out as a grid. | Ensure the parent has display: grid (not inline-grid unless needed). |
fr units not working as expected. | Avoid mixing fr with auto (auto takes priority). Use minmax() for flexibility. |
| Gaps causing horizontal overflow. | Use box-sizing: border-box on all elements (include gaps in total width). |
| Overlapping items. | Check grid-column/grid-row values—ensure they don’t span the same area unintentionally. |
14. Conclusion
CSS Grid is a powerful tool for building flexible, responsive layouts with minimal code. Its two-dimensional nature, intuitive alignment controls, and support for visual templates (via grid-template-areas) make it indispensable for modern web design.
To master Grid:
- Practice with simple layouts first (e.g., card grids).
- Experiment with
grid-template-areasfor visual clarity. - Combine Grid with Flexbox for component-level layouts (e.g., Grid for page structure, Flexbox for card content).
With Grid, you’ll spend less time hacking layouts and more time creating seamless user experiences.
15. References
- MDN Web Docs: CSS Grid Layout
- CSS-Tricks: A Complete Guide to Grid
- Grid by Example (Rachel Andrew’s tutorials)
- Grid Garden (Interactive game to learn Grid)
- Firefox DevTools Grid Inspector (Debug grids visually)