CSSgrid-column & grid-row

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).