X Xerobit

CSS Grid Auto Placement — How grid-auto-flow Works

CSS grid auto-placement automatically positions items in the grid without explicit placement rules. Here's how grid-auto-flow, grid-auto-rows, and grid-auto-columns work — and...

Mian Ali Khalid · · 4 min read
Use the tool
CSS Grid Generator
Visual CSS Grid layout builder. Configure columns, rows, gaps, and named areas. Live preview with copyable CSS output.
Open CSS Grid Generator →

CSS grid’s auto-placement algorithm decides where to put items you don’t explicitly position. By default, items flow into rows left-to-right. You can control this with grid-auto-flow, grid-auto-rows, and grid-auto-columns.

Use the CSS Grid Generator to visualize grid layouts.

Default auto-placement: row flow

.grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
}

With 7 items, auto-placement fills left-to-right, top-to-bottom:

[1] [2] [3]
[4] [5] [6]
[7]

The grid creates a new row (an implicit row) for item 7 automatically.

grid-auto-flow property

grid-auto-flow: row;       /* default: fill rows left-to-right */
grid-auto-flow: column;    /* fill columns top-to-bottom */
grid-auto-flow: row dense; /* fill gaps when items vary in size */
grid-auto-flow: column dense;

Column flow

.vertical-grid {
  display: grid;
  grid-template-rows: repeat(3, 100px);
  grid-auto-flow: column;
}

Items flow down columns:

[1] [4] [7]
[2] [5]
[3] [6]

Dense packing

dense fills holes caused by differently-sized items:

.masonry-like {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  grid-auto-flow: row dense;
  gap: 1rem;
}

Without dense:

[1:2×2] [2:1×1] [3:1×1]
[   1  ] [4:3×1         ]
[5:1×1] [6:1×1]

With dense:

[1:2×2] [2:1×1] [3:1×1]
[   1  ] [5:1×1] [6:1×1]
[4:3×1              ]

Dense backfills smaller items into earlier gaps.

Implicit tracks: grid-auto-rows and grid-auto-columns

When items flow into positions beyond your explicit grid definition, CSS creates implicit tracks. Size them with grid-auto-rows and grid-auto-columns:

.grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: 200px;  /* only first row is explicit */
  grid-auto-rows: 120px;      /* all implicit rows are 120px */
}
/* Variable height rows that never collapse below 100px: */
.card-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  grid-auto-rows: minmax(160px, auto);
  gap: 1.5rem;
}

Alternating row heights

.alternate-rows {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  grid-auto-rows: 100px 200px;  /* alternates: 100px, 200px, 100px, 200px... */
}

Controlling explicit vs implicit placement

Items with explicit placement (grid-column, grid-row) are placed first; remaining items fill the gaps:

.grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  grid-auto-rows: 100px;
}

/* This item takes the top-right corner explicitly: */
.featured {
  grid-column: 3 / 5;  /* columns 3–4 */
  grid-row: 1 / 3;     /* rows 1–2 */
}

/* All other items auto-place around the featured item: */

Auto-placement with spans

Items can span multiple tracks while still using auto-placement:

.item-wide {
  grid-column: span 2;  /* takes 2 columns, auto-placed */
}

.item-tall {
  grid-row: span 3;     /* takes 3 rows, auto-placed */
}

Combined with dense:

.gallery {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  grid-auto-rows: 150px;
  grid-auto-flow: dense;
  gap: 0.5rem;
}

.wide { grid-column: span 2; }
.tall { grid-row: span 2; }
.large { grid-column: span 2; grid-row: span 2; }

This creates a Pinterest-like layout where large items coexist with small ones.

Auto-placement in column flow

.navigation {
  display: grid;
  grid-template-rows: repeat(4, 50px);
  grid-auto-flow: column;
  grid-auto-columns: minmax(150px, max-content);
  gap: 1rem;
}

Items flow into columns, creating new columns as needed.

Ordering vs placement

order property reorders visual display without changing source order or auto-placement:

.grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
}

/* This item appears last visually, but is still auto-placed in document order: */
.first-item { order: -1; }
.last-item { order: 1; }

Note: changing order can confuse keyboard navigation (tab order follows source order, not visual order). Use explicit placement instead for accessibility.

Debugging auto-placement

Browser DevTools (Chrome, Firefox) show the grid overlay including implicit tracks:

  1. Inspect any grid container
  2. Click the “grid” badge in the DOM inspector
  3. See explicit tracks (solid lines) vs implicit tracks (dashed lines)

Related posts

Related tool

CSS Grid Generator

Visual CSS Grid layout builder. Configure columns, rows, gaps, and named areas. Live preview with copyable CSS output.

Written by Mian Ali Khalid. Part of the Frontend & Design pillar.