Table of Contents
- What is CSS Grid?
- Core Concepts: Grid Fundamentals
- Getting Started: Setting Up a Grid Container
- Essential Grid Container Properties
- Grid Item Properties: Controlling Individual Items
- Implicit vs. Explicit Grids
- Practical Examples: From Simple to Complex
- Pro Tips for Mastering CSS Grid
- Browser Support
- Conclusion
- References
What is CSS Grid?
CSS Grid Layout is a two-dimensional layout system for the web, designed to handle both rows and columns simultaneously. It allows you to define a grid container and place child elements (grid items) within predefined rows and columns, with granular control over their size, position, and alignment.
Key advantages of Grid:
- Declarative: Define the layout structure directly in CSS, no need for complex JavaScript or hacky workarounds.
- Flexibility: Items can span multiple rows/columns, overlap, or be precisely positioned.
- Responsiveness: Built-in tools like
frunits,minmax(), andrepeat()simplify adaptive designs. - Semantics: Works with semantic HTML; no need for extra wrapper divs (unlike some older techniques).
Core Concepts: Grid Fundamentals
Before diving into properties, let’s define the building blocks of a CSS Grid:
| Term | Definition |
|---|---|
| Grid Container | The parent element with display: grid; all direct children become grid items. |
| Grid Items | Direct children of the grid container (nested elements are not grid items unless their parent is a grid container). |
| Grid Tracks | The spaces between grid lines (i.e., rows and columns). Track size is defined with grid-template-columns (columns) and grid-template-rows (rows). |
| Grid Lines | The dividing lines that form the grid’s structure (numbered starting at 1, or named for clarity). |
| Grid Cell | The intersection of a row and column (like a cell in a table). |
| Grid Area | A rectangular region of the grid, composed of one or more adjacent cells. |
Visualizing the Grid: Imagine a spreadsheet with rows and columns. The lines separating columns are column lines, and those separating rows are row lines. The spaces between lines are tracks (columns/rows), and the intersections are cells. A grid area might span 2 columns and 3 rows, combining multiple cells.
Getting Started: Setting Up a Grid Container
To create a grid, first define a grid container by setting display: grid (or display: inline-grid for inline-level grids) on a parent element. All direct children of this container automatically become grid items.
.grid-container {
display: grid; /* Establishes a grid container */
}
By default, a grid container has:
- 1 column track (width:
auto, i.e., as wide as the content). - Rows sized to fit their content (
autoheight).
Essential Grid Container Properties
Grid containers control the overall structure of the grid, including track sizes, spacing, and item flow.
Defining Columns and Rows: grid-template-columns & grid-template-rows
These properties define the explicit tracks (columns and rows) of the grid. Use them to specify the number of tracks and their sizes.
Syntax:
grid-template-columns: <track-size> ...; /* For columns */
grid-template-rows: <track-size> ...; /* For rows */
Track Size Values:
- Lengths: Fixed units like
px,em, orrem(e.g.,200px). - Percentages: Relative to the container size (e.g.,
30%). frunits: Flexible fractions of the remaining space (e.g.,1fr= 1 part of available space).minmax(min, max): Defines a track size with a minimum and maximum (e.g.,minmax(150px, 1fr)ensures columns don’t shrink below 150px).repeat(count, size): Repeats a track sizecounttimes (e.g.,repeat(3, 1fr)=1fr 1fr 1fr).
Example 1: 3 Equal Columns
.grid-container {
display: grid;
grid-template-columns: 1fr 1fr 1fr; /* 3 columns, each taking 1/3 of space */
}
Example 2: Responsive Columns with minmax()
.grid-container {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); /* Columns wrap to new rows if <200px */
}
auto-fit automatically adjusts the number of columns to fit the container, making this ideal for responsive galleries.
Spacing with gap
The gap property (shorthand for row-gap and column-gap) adds space between grid items (not around the container edges).
Syntax:
gap: <row-gap> <column-gap>; /* Shorthand */
row-gap: <size>; /* Space between rows */
column-gap: <size>; /* Space between columns */
Example:
.grid-container {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 20px; /* 20px gap between all rows and columns */
}
Controlling Item Placement: grid-auto-flow
By default, grid items fill the grid row by row (left-to-right, top-to-bottom). grid-auto-flow lets you change this behavior:
row(default): Fill rows first.column: Fill columns first (top-to-bottom, left-to-right).dense: Attempt to fill gaps left by larger items (avoids empty spaces).
Example: Column-First Flow
.grid-container {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-auto-flow: column; /* Items fill columns first */
}
Aligning the Grid: justify-content & align-content
These properties align the entire grid within the container when the grid is smaller than the container (e.g., if tracks have fixed sizes).
justify-content: Aligns along the inline (horizontal) axis.align-content: Aligns along the block (vertical) axis.
Common values: start, center, end, space-between, space-around, space-evenly.
Example: Centering the Grid
.grid-container {
display: grid;
grid-template-columns: repeat(3, 100px); /* Fixed column size */
height: 500px; /* Container taller than grid */
justify-content: center; /* Center grid horizontally */
align-content: center; /* Center grid vertically */
}
Sizing Implicit Tracks: grid-auto-columns & grid-auto-rows
Implicit tracks are created when items are placed outside the explicitly defined grid (e.g., more items than tracks). Use these properties to control their size (default: auto).
Example:
.grid-container {
display: grid;
grid-template-columns: repeat(3, 1fr); /* 3 explicit columns */
grid-auto-rows: 150px; /* All implicit rows (new rows) will be 150px tall */
}
Grid Item Properties: Controlling Individual Items
Grid items are direct children of the grid container. Use these properties to customize their placement and size.
Spanning Rows and Columns: grid-column & grid-row
These shorthand properties let items span multiple tracks by defining their start and end positions along grid lines.
Syntax:
grid-column: <start-line> / <end-line>; /* Shorthand for grid-column-start / grid-column-end */
grid-row: <start-line> / <end-line>; /* Shorthand for grid-row-start / grid-row-end */
Grid lines are numbered starting at 1 (e.g., a 3-column grid has 4 column lines: 1, 2, 3, 4).
Example: Span 2 Columns
.item-2 {
grid-column: 2 / 4; /* Starts at column line 2, ends at line 4 (spans columns 2 and 3) */
}
Using span:
Instead of line numbers, use span <n> to span n tracks:
.item-3 {
grid-row: span 2; /* Spans 2 rows */
}
Named Areas: grid-area & grid-template-areas
For semantic, readable layouts, name grid areas and place items by name.
- Define areas in the container with
grid-template-areas. - Assign items to areas with
grid-area.
Example: Page Layout with Named Areas
/* Grid Container */
.page-layout {
display: grid;
grid-template-columns: 200px 1fr; /* Sidebar (200px) + Main (remaining space) */
grid-template-rows: auto 1fr auto; /* Header/Footer (auto height) + Main (remaining space) */
grid-template-areas:
"header header" /* Header spans both columns */
"sidebar main" /* Sidebar in first column, main in second */
"footer footer"; /* Footer spans both columns */
height: 100vh; /* Full viewport height */
}
/* Grid Items */
.header { grid-area: header; }
.sidebar { grid-area: sidebar; }
.main { grid-area: main; }
.footer { grid-area: footer; }
Use . to denote empty cells (e.g., grid-template-areas: "header ." "sidebar main" leaves a gap in the header row).
Aligning Items: justify-self & align-self
These properties align individual items within their grid cell (overriding container-level alignment).
justify-self: Aligns along the inline (horizontal) axis.align-self: Aligns along the block (vertical) axis.
Values: start, center, end, stretch (default).
Example: Centering an Item
.special-item {
justify-self: center; /* Center horizontally in its cell */
align-self: center; /* Center vertically in its cell */
}
Implicit vs. Explicit Grids
- Explicit Grid: Tracks defined with
grid-template-columnsandgrid-template-rows. - Implicit Grid: Tracks created automatically to accommodate items placed outside the explicit grid (e.g., extra rows/columns when there are more items than tracks).
Example: If you define 3 columns but have 10 items, Grid will create implicit rows to fit the extra items. Use grid-auto-rows to control their height.
Practical Examples: From Simple to Complex
Example 1: Basic Photo Gallery
A responsive gallery with 3 columns on desktop, 2 on tablets, and 1 on mobile.
<div class="gallery">
<img src="img1.jpg" alt="Photo 1">
<img src="img2.jpg" alt="Photo 2">
<img src="img3.jpg" alt="Photo 3">
<img src="img4.jpg" alt="Photo 4">
<img src="img5.jpg" alt="Photo 5">
<img src="img6.jpg" alt="Photo 6">
</div>
.gallery {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); /* Responsive columns */
gap: 1rem;
padding: 1rem;
}
.gallery img {
width: 100%;
height: 200px;
object-fit: cover; /* Crop images to fit */
}
/* Mobile: 1 column */
@media (max-width: 600px) {
.gallery {
grid-template-columns: 1fr;
}
}
Example 2: Responsive Page Layout (Header, Sidebar, Main, Footer)
A classic layout with a full-width header/footer, sidebar, and main content.
<div class="page">
<header>Header</header>
<aside>Sidebar</aside>
<main>Main Content</main>
<footer>Footer</footer>
</div>
.page {
display: grid;
grid-template-columns: 1fr 3fr; /* Sidebar (1/4) + Main (3/4) */
grid-template-rows: auto 1fr auto; /* Header/Footer: auto | Main: fill space */
grid-template-areas:
"header header"
"sidebar main"
"footer footer";
min-height: 100vh; /* Full viewport height */
gap: 1rem;
padding: 1rem;
}
header { grid-area: header; background: #f0f0f0; padding: 1rem; }
aside { grid-area: sidebar; background: #e0e0e0; padding: 1rem; }
main { grid-area: main; background: #d0d0d0; padding: 1rem; }
footer { grid-area: footer; background: #f0f0f0; padding: 1rem; }
/* Mobile: Stack sidebar below main */
@media (max-width: 768px) {
.page {
grid-template-columns: 1fr; /* 1 column */
grid-template-areas:
"header"
"main"
"sidebar"
"footer";
}
}
Example 3: Dashboard with Asymmetric Widgets
A dashboard with widgets of varying sizes (some spanning 2 columns/rows).
<div class="dashboard">
<div class="widget">Widget 1</div>
<div class="widget big">Widget 2 (Big)</div>
<div class="widget">Widget 3</div>
<div class="widget tall">Widget 4 (Tall)</div>
<div class="widget">Widget 5</div>
</div>
.dashboard {
display: grid;
grid-template-columns: repeat(4, 1fr); /* 4 columns */
grid-auto-rows: 150px; /* Implicit rows: 150px tall */
gap: 1rem;
padding: 1rem;
}
.widget {
background: #fff;
padding: 1rem;
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}
.big {
grid-column: span 2; /* Span 2 columns */
grid-row: span 1; /* Span 1 row */
}
.tall {
grid-row: span 2; /* Span 2 rows */
}
Pro Tips for Mastering CSS Grid
- Use the Browser Grid Inspector: Modern browsers (Chrome, Firefox) have built-in Grid tools (DevTools → Elements → Layout) to visualize grid lines, tracks, and areas.
- Combine Grid and Flexbox: Use Grid for page-level layout and Flexbox for component-level alignment (e.g., aligning content inside a grid item).
- Prefer
frUnits for Flexibility:frunits distribute space proportionally, making layouts more robust than fixed pixels. - Leverage
minmax()for Responsiveness:minmax(min, max)ensures tracks don’t shrink below a minimum size or grow beyond a maximum. - Test with
grid-template-areasFirst: For complex layouts, sketching with named areas (e.g., “header header” “sidebar main”) makes the structure easier to visualize.
Browser Support
CSS Grid is supported in all modern browsers (Chrome, Firefox, Safari, Edge) since 2017. Internet Explorer 11 has partial support but uses an older, prefixed syntax (avoid unless supporting legacy systems).
Check caniuse.com for the latest stats.
Conclusion
CSS Grid is a transformative tool for web layout, enabling developers to create complex, responsive designs with clean, maintainable code. By mastering its core concepts—containers, tracks, items, and alignment—you’ll unlock the ability to build everything from simple galleries to sophisticated dashboards with ease.
The key to mastery is practice: experiment with track sizes, item placement, and real-world examples. As you build, you’ll discover how Grid simplifies once-challenging layouts, making your code more semantic and your workflow more efficient.
References
- MDN Web Docs: CSS Grid Layout
- CSS-Tricks: A Complete Guide to Grid
- Grid by Example (Rachel Andrew, Grid expert)
- W3C CSS Grid Specification