Difficulty: Intermediate
CSS Grid Layout is a two-dimensional layout system that allows you to control both columns and rows simultaneously. Unlike Flexbox, which works along a single axis at a time, Grid lets you define a complete grid structure and place items into specific cells, rows, or columns. It is the most powerful layout system in CSS and is ideal for full page layouts, complex component designs, and any scenario where you need precise control over both dimensions.
To create a grid container, set display: grid on an element. All direct children of the grid container automatically become grid items. The container itself behaves as a block-level element. You can also use display: inline-grid for an inline-level grid container. By default, a grid container with no template definitions stacks items in a single column, similar to normal block flow.
The grid-template-columns property defines the number and size of columns in the grid. Each value in the property creates one column. You can use fixed sizes (200px), percentages (25%), flexible units (1fr), or sizing functions like minmax() and auto. For example, grid-template-columns: 200px 1fr 200px creates a three-column layout with fixed sidebars and a flexible center. The fr unit (fraction) distributes available space proportionally -- 1fr 2fr 1fr creates three columns where the middle column is twice as wide as the side columns.
The grid-template-rows property works exactly like grid-template-columns but for rows. It defines the height of each row. If you define fewer row templates than there are rows of items, additional rows are created automatically as implicit rows. You can control the size of implicit rows with grid-auto-rows. For example, grid-auto-rows: minmax(100px, auto) ensures that automatically created rows are at least 100px tall but can grow to fit their content.
The gap property (or its longhand forms row-gap and column-gap) adds spacing between grid cells, just as it does in Flexbox. The gap shorthand takes one value for uniform spacing or two values for row-gap and column-gap respectively. Unlike margins, gap only adds space between cells, not at the outer edges of the grid.
.grid {
display: grid;
grid-template-columns: 200px 200px 200px;
grid-template-rows: 100px 100px;
gap: 16px;
}
.grid-item {
background-color: #3b82f6;
color: white;
padding: 16px;
border-radius: 8px;
}
This creates a 3-column, 2-row grid with fixed sizes. Each cell is 200px wide and 100px tall with 16px gaps between them. If there are more than 6 items, additional rows are created automatically.
/* Equal columns */
.equal-grid {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
gap: 24px;
}
/* Weighted columns */
.weighted-grid {
display: grid;
grid-template-columns: 1fr 2fr 1fr;
gap: 24px;
}
/* Sidebar + main layout */
.layout-grid {
display: grid;
grid-template-columns: 250px 1fr;
gap: 24px;
min-height: 100vh;
}
The fr unit distributes available space. 1fr 1fr 1fr creates three equal columns. 1fr 2fr 1fr makes the middle column twice as wide. Mixing px and fr lets you create fixed sidebars with flexible main areas.
/* Explicit rows: define exact row heights */
.explicit-grid {
display: grid;
grid-template-columns: 1fr 1fr;
grid-template-rows: 80px 200px 80px;
gap: 16px;
}
/* Auto rows: set height for dynamically created rows */
.auto-grid {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
grid-auto-rows: minmax(150px, auto);
gap: 16px;
}
grid-template-rows defines the height of each explicit row. grid-auto-rows sets the height for rows created automatically when items overflow the explicit grid. minmax(150px, auto) means at least 150px tall but grows to fit content.
.dashboard {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
grid-template-rows: auto 1fr;
row-gap: 32px;
column-gap: 16px;
padding: 24px;
}
/* Shorthand: gap: <row-gap> <column-gap> */
.dashboard-short {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
gap: 32px 16px;
}
row-gap and column-gap can be set independently for different vertical and horizontal spacing. The gap shorthand takes the row value first and the column value second. A single value sets both to the same amount.
display:grid, grid-template-columns, grid-template-rows, Two-Dimensional Layout