grid-column & grid-row placement
grid-column and grid-row position individual grid items by specifying which columns and rows they occupy. You can use line numbers, spanning, or named lines. These properties give you precise control over item placement within the grid.
Basic placement with line numbers
CSS
<!-- Grid line numbering -->
.grid {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
grid-template-rows: 1fr 1fr;
}
<!-- Grid lines: 1, 2, 3, 4 (for 3 columns) -->
<!-- Row lines: 1, 2, 3 (for 2 rows) -->
/* Placing an item from line 1 to 3 -->
.item {
grid-column: 1 / 3; /* spans from column 1 to 3 -->
grid-row: 1 / 2; /* stays in row 1 -->
}
<!-- [Item spans 2 cols] [3rd col empty] -->
/* Using start only (spans to end) -->
.item {
grid-column: 2; /* starts at column 2, spans to end -->
}
<!-- [col1] [Item spans 2 cols] -->
/* Using span keyword -->
.item {
grid-column: 1 / span 2; /* starts at 1, spans 2 columns -->
grid-row: 1 / span 1; /* spans 1 row -->
}
<!-- [Item spans 2 cols] [col3] -->
/* Simplified span syntax -->
.item {
grid-column: span 3; /* spans 3 columns from current position -->
grid-row: span 2; /* spans 2 rows from current position -->
}Practical placement patterns
Property | Value | Result |
|---|---|---|
grid-column | 1 / 3 | Spans columns 1-2 (line 1 to line 3) |
grid-column | span 2 | Spans 2 columns from current |
grid-column | 2 | Starts at column 2, ends at grid edge |
grid-row | 1 / -1 | Spans all rows (line 1 to last) |
grid-row | span 3 | Spans 3 rows from current |
CSS
<!-- Holy Grail layout -->
<div class="page">
<header>Header</header>
<nav>Nav</nav>
<main>Main</main>
<aside>Sidebar</aside>
<footer>Footer</footer>
</div>
.page {
display: grid;
grid-template-columns: 200px 1fr 200px;
grid-template-rows: auto 1fr auto;
gap: 20px;
}
header {
grid-column: 1 / -1; /* span all columns -->
}
nav {
grid-column: 1;
grid-row: 2;
}
main {
grid-column: 2;
grid-row: 2;
}
aside {
grid-column: 3;
grid-row: 2;
}
footer {
grid-column: 1 / -1; /* span all columns -->
}
<!-- Header spans all columns -->
<!-- Nav, main, sidebar in row 2 -->
<!-- Footer spans all columns -->
/* Asymmetric layout */
.layout {
display: grid;
grid-template-columns: 1fr 2fr 1fr;
gap: 20px;
}
.featured {
grid-column: 1 / 3; /* spans 2 columns -->
grid-row: 1;
}
.sidebar {
grid-column: 3;
grid-row: 1 / 3; /* spans 2 rows -->
}
.items {
grid-column: 1 / 3;
grid-row: 2;
}
<!-- Featured item wide -->
<!-- Sidebar tall -->
<!-- Items below featured -->
/* Magazine-style grid -->
.magazine {
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-template-rows: repeat(4, 200px);
gap: 20px;
}
.hero {
grid-column: 1 / 3; /* 2 columns -->
grid-row: 1 / 3; /* 2 rows (big square) -->
}
.side1 {
grid-column: 3 / 5; /* 2 columns -->
grid-row: 1 / 3; /* 2 rows -->
}
.items {
grid-column: 1 / -1; /* full width -->
grid-row: 3 / -1; /* remaining rows -->
}Using -1 for end position
CSS
<!-- -1 refers to the final grid line -->
.grid {
display: grid;
grid-template-columns: repeat(4, 1fr);
}
/* Item spans from column 1 to the last -->
.item {
grid-column: 1 / -1; /* spans entire width -->
}
<!-- [Item spans all 4 columns] -->
/* Item spans from column 2 to last -->
.item {
grid-column: 2 / -1; /* columns 2, 3, 4 -->
}
<!-- [col1] [Item spans cols 2-4] -->
/* Relative to grid size -->
.item {
grid-row: 1 / -1; /* spans all rows -->
}
<!-- Item goes full height -->
/* Without -1 (must know grid size) -->
.item {
grid-column: 1 / 5; /* manual end line (assumes 4 columns) -->
grid-row: 1 / 4; /* manual end line (assumes 3 rows) -->
}
<!-- Works but requires knowing exact grid -->
/* With -1 (automatic) -->
.item {
grid-column: 1 / -1; /* always spans full width -->
grid-row: 1 / -1; /* always spans full height -->
}
<!-- Works regardless of grid size -->Auto-placement and implicit grid
CSS
<!-- Without explicit placement, items auto-place -->
.grid {
display: grid;
grid-template-columns: 1fr 1fr;
grid-template-rows: 200px 200px;
}
.item {
/* No grid-column or grid-row specified -->
/* Items fill cells left-to-right, top-to-bottom -->
}
<!-- [Item1] [Item2] -->
<!-- [Item3] [Item4] -->
/* Mixing explicit and auto placement -->
.grid {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
grid-template-rows: 1fr 1fr;
}
.item1 {
/* Auto-placed -->
}
.item2 {
grid-column: 2;
grid-row: 1;
/* Explicitly placed in middle-top -->
}
.item3 {
/* Auto-placed in remaining cell -->
}
<!-- Item2 placed in grid-column 2 -->
<!-- Other items fill remaining cells -->
/* grid-auto-flow controls auto-placement direction -->
.grid {
display: grid;
grid-auto-flow: column; /* auto-place left-to-right first -->
grid-template-columns: repeat(auto-fill, minmax(100px, 1fr));
}
<!-- Items flow across rows first, then down -->Advanced: Dense packing
CSS
<!-- grid-auto-flow: dense fills holes -->
.grid {
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-auto-flow: dense; /* fill gaps -->
}
.big {
grid-column: span 2;
}
.small {
grid-column: span 1;
}
<!-- Dense packing fills gaps created by large items -->
/* Practical example: flexible grid -->
.items {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
grid-auto-flow: dense;
gap: 10px;
}
.featured {
grid-column: span 2;
grid-row: span 2;
}
.normal {
grid-column: span 1;
grid-row: span 1;
}
<!-- Featured items span larger areas -->
<!-- Dense packing optimizes layout -->Note
`grid-column` and `grid-row` control item placement using line numbers. Use `1 / 3` to span from line 1 to 3, `span 2` to span 2 units, and `-1` to reference the final grid line. Items auto-place if not explicitly positioned, filling cells sequentially.
Next
Named grid areas: [grid-template-areas](/css/grid-template-areas).