Guide to CSS Grid Layout: From Basics to Advanced Techniques
CSS Grid Layout is the most powerful layout system available in CSS. It's a two-dimensional system that can handle both columns and rows simultaneously, unlike Flexbox which is primarily one-dimensional. Grid has fundamentally changed how we build web layouts — replacing float-based hacks, complex framework grids, and even reducing the need for media queries in many cases.
This guide will take you from the basics of CSS Grid to advanced patterns you can use in production. Whether you're building a simple card layout or a complex dashboard, Grid has you covered.
Grid Fundamentals
CSS Grid works with two key concepts: the grid container (the parent) and grid items (the children). You create a grid by setting display: grid on the container, then defining columns and rows.
.container {
display: grid;
grid-template-columns: 200px 1fr 200px;
grid-template-rows: auto 1fr auto;
gap: 16px;
}
This creates a three-column layout where the sidebar columns are 200px wide and the middle column takes up the remaining space. The gap property adds spacing between grid items without needing margins.
Defining Columns and Rows
Fixed and Flexible Sizes
Grid tracks (columns and rows) can use any CSS length unit:
px— fixed pixel size%— percentage of the containerfr— fraction of available space (the star of CSS Grid)auto— sized by contentmin-content/max-content— intrinsic sizing
The fr unit is unique to Grid. It distributes remaining space proportionally. 1fr 2fr 1fr creates three columns where the middle one is twice as wide as the others.
The repeat() Function
Instead of writing 1fr 1fr 1fr 1fr, use the repeat() function:
grid-template-columns: repeat(4, 1fr); /* 4 equal columns */ grid-template-columns: repeat(3, 1fr 2fr); /* alternating pattern */ grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); /* responsive! */
The last example is one of the most powerful patterns in CSS Grid — it creates a responsive grid that automatically adjusts the number of columns based on available space, without any media queries.
The minmax() Function
minmax(min, max) defines a size range. The track will be at least min wide but won't exceed max. This is essential for responsive layouts:
grid-template-columns: minmax(200px, 300px) 1fr; /* Sidebar: 200-300px, Main: rest of space */
Placing Items on the Grid
Line-Based Placement
Grid lines are numbered starting from 1. You can place items by specifying their start and end lines:
.item {
grid-column: 1 / 3; /* spans columns 1 and 2 */
grid-row: 1 / 2; /* spans row 1 only */
}
/* Shorthand with span */
.item {
grid-column: 1 / span 2; /* start at 1, span 2 columns */
}
Named Grid Lines
You can name grid lines for more readable code:
.container {
grid-template-columns: [sidebar-start] 250px [sidebar-end main-start] 1fr [main-end];
}
.sidebar {
grid-column: sidebar-start / sidebar-end;
}
Grid Template Areas
One of Grid's most intuitive features is template areas. You can name regions of your grid and place items by name:
.container {
display: grid;
grid-template-areas:
"header header header"
"sidebar content aside"
"footer footer footer";
grid-template-columns: 200px 1fr 200px;
grid-template-rows: auto 1fr auto;
}
.header { grid-area: header; }
.sidebar { grid-area: sidebar; }
.content { grid-area: content; }
.aside { grid-area: aside; }
.footer { grid-area: footer; }
This creates a classic page layout that's instantly readable. You can even use a dot (.) to leave cells empty.
Alignment and Justification
Grid provides powerful alignment controls at both the container and item level:
Container-Level Alignment
justify-items— aligns items horizontally within their cellalign-items— aligns items vertically within their celljustify-content— positions the entire grid horizontallyalign-content— positions the entire grid verticallyplace-items— shorthand for align-items + justify-itemsplace-content— shorthand for align-content + justify-content
Item-Level Alignment
Individual items can override the container's alignment:
.item {
justify-self: center; /* horizontal alignment */
align-self: end; /* vertical alignment */
place-self: center end; /* shorthand */
}
Auto-Placement and Implicit Grids
When you have more items than defined grid cells, Grid creates new rows automatically. This is the implicit grid. You can control how these implicit tracks are sized:
.container {
grid-auto-rows: minmax(100px, auto); /* implicit rows */
grid-auto-flow: dense; /* fill gaps */
}
The grid-auto-flow: dense property tells Grid to fill in gaps left by larger items. This is useful for masonry-like layouts where you want items to pack tightly.
Responsive Grid Patterns
Auto-Fit vs Auto-Fill
Both create responsive grids, but with a subtle difference:
/* auto-fill: keeps empty tracks */ grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); /* auto-fit: collapses empty tracks */ grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
With auto-fit, if you have fewer items than columns, the items stretch to fill the space. With auto-fill, the empty columns remain, keeping items at their minimum size.
Responsive Layout Without Media Queries
.cards {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(min(100%, 300px), 1fr));
gap: 24px;
}
This creates a card grid that's responsive without a single media query. The min(100%, 300px) prevents overflow on very small screens.
Common Grid Layout Patterns
Holy Grail Layout
.page {
display: grid;
grid-template: auto 1fr auto / 200px 1fr 200px;
grid-template-areas:
"header header header"
"nav main aside"
"footer footer footer";
min-height: 100vh;
}
Centered Content
.container {
display: grid;
place-items: center;
min-height: 100vh;
}
The simplest way to center anything, both vertically and horizontally.
Sidebar Layout
.layout {
display: grid;
grid-template-columns: minmax(200px, 25%) 1fr;
gap: 24px;
}
Grid vs Flexbox: When to Use Each
Grid and Flexbox are complementary, not competing. Use Grid when you need two-dimensional control (rows AND columns), when you want to define the layout from the container, or when you have a complex page structure. Use Flexbox for one-dimensional layouts, component-level alignment, and when items should dictate their own size.
In practice, most layouts use both: Grid for the page structure and Flexbox for components within grid cells.
Conclusion
CSS Grid has transformed web layout from a series of clever hacks into a proper layout system. With features like fr units, template areas, auto-placement, and minmax(), you can build complex, responsive layouts with clean, readable code. Start with simple grids and gradually explore advanced features — the more you use Grid, the more you'll realize how much it simplifies your CSS.