CSS Grid Auto-Flow Playground

Interactively test how CSS Grid row, column, and dense auto-placement rules position multi-span elements without vacant layout holes

⚡ Simulation Presets:
Distinct Profile Name

1. Grid Auto-Flow Direction & Packing

Dense Mode Active: Browser scans backward in the track sequence to fill earlier holes when smaller items fit.

2. Container Grid Tracks

Cols (4)
4
Rows (4)
4
Gap (16px)
16

3. Child Items (8)

1 Item 1
Col:1
Row:1
2 Item 2
Col:2
Row:2
3 Item 3
Col:1
Row:1
4 Item 4
Col:1
Row:2
5 Item 5
Col:2
Row:1
6 Item 6
Col:1
Row:1
7 Item 7
Col:2
Row:1
8 Item 8
Col:1
Row:1
#1 1x1
span 1 / 1
#2 2x2
span 2 / 2
#3 1x1
span 1 / 1
#4 1x2
span 1 / 2
#5 2x1
span 2 / 1
#6 1x1
span 1 / 1
#7 2x1
span 2 / 1
#8 1x1
span 1 / 1
Flow Rule grid-auto-flow: row dense
Matrix Tracks 4 Cols × 4 Rows
Execution Model 100% Client-Side

Mastering the CSS Grid Auto-Placement Algorithm: In-Depth Engineering of grid-auto-flow, Dense Packing, and Layout Cohesion

CSS Grid Level 1 and Level 2 represent the most powerful two-dimensional layout systems natively built into modern web rendering engines. While declaring explicit track templates using grid-template-columns and grid-template-rows establishes the geometric scaffolding, real-world web applications rarely deal with static, uniformly sized items. Asynchronous content streams, variable-span dashboard metric cards, multi-column media galleries, and editorial magazine mosaics demand dynamic item positioning. At the very center of this automated arrangement lies the CSS Grid Auto-Placement Algorithm, orchestrated by the grid-auto-flow property.

Deconstructing grid-auto-flow: The Four Operational Modes

The grid-auto-flow CSS property controls how the browser’s auto-placement cursor steps through implicit and explicit tracks when items do not have explicitly declared coordinates (such as grid-column: 2 / 4). It accepts four primary configurations:

1. grid-auto-flow: row (The Default)

The auto-placement algorithm traverses the grid horizontally. It attempts to fit each successive item in the current row. If an item specifies a multi-column span that exceeds the remaining slots in that row, the cursor immediately wraps to the beginning of the next row. Crucially, in standard row mode, the placement cursor never moves backwards. Any vacant cells left behind in the previous row remain empty holes in the visual layout.

2. grid-auto-flow: column

The traversal axis flips 90 degrees. The placement engine attempts to fill tracks vertically downwards before starting a new column track to the right. If an item spans multiple rows and cannot fit in the remaining space of the current column, the engine advances to the next column. Just like standard row flow, vacant tracks previously bypassed are never backfilled.

3. grid-auto-flow: row dense

The "dense" packing algorithm fundamentally alters cursor traversal. When a large or multi-span item causes a line wrap—leaving behind unoccupied grid cells—the algorithm does not abandon those cells. Instead, as subsequent smaller items are evaluated from the DOM stream, the engine resets its cursor to the earliest available gap in the grid. If a subsequent item fits into an earlier vacant pocket, it is inserted there regardless of its original source order position.

4. grid-auto-flow: column dense

Applies the dense packing algorithm along the column axis. Items stream downwards into vertical tracks. When multi-row elements advance to the next column, subsequent 1x1 or smaller items backfill empty vertical gaps left in preceding columns. This creates a compact, masonry-style waterfall appearance without requiring external JavaScript layout libraries.

Algorithmic Deep Dive: How the W3C Grid Auto-Placement Algorithm Executes

To fully leverage dense packing, front-end engineers must understand the multi-stage resolution process defined in the W3C CSS Grid specification:

  1. Phase 1: Position Explicitly Placed Items: Any grid child with concrete coordinate declarations (e.g., grid-column-start: 1, grid-row-start: 2) is positioned first. Their assigned cells are locked and marked as occupied.
  2. Phase 2: Position Items with Definite Row Positions: Elements that define a specific row but an automatic column are resolved next, marching across their designated row to find the first open track that fits their column span.
  3. Phase 3: Position Items with Definite Column Positions: Elements with definite columns but auto rows are placed next, stepping down their specified column track.
  4. Phase 4: Auto-Placement of Remaining Items: This is where grid-auto-flow governs execution. For each completely auto-placed child:
    • If dense is omitted: The cursor starts from its previous position. It searches forward only. Unused cells prior to the current cursor position are permanently locked out for this pass.
    • If dense is specified: For every single item, the cursor restarts at (1, 1). It tests every empty coordinate slot sequentially until it finds a block of continuous cells matching both the item’s colSpan and rowSpan.

The Accessibility Dilemma: Visual Reordering vs. DOM Focus Order

While grid-auto-flow: dense produces aesthetically pleasing, gap-free layouts, it introduces a severe accessibility (a11y) hazard under WCAG 2.1 Success Criterion 1.3.2 (Meaningful Sequence) and Criterion 2.4.3 (Focus Order).

Because dense packing reorders elements visually to fill empty pockets, the visual position of an item may differ drastically from its position in the HTML document tree. Sighted keyboard users pressing the Tab key follow the DOM source order, causing the focus indicator to jump erratically across the screen—skipping forward over a large card, then jumping backward into a newly backfilled small item.

Engineering Rule: Only use dense auto-placement when items are non-interactive (e.g., photo galleries, decorative graphic mosaics) or when the reading sequence is truly non-linear. For interactive cards with buttons, forms, or tab targets, prefer explicit placement or ensure the DOM ordering matches the visual hierarchy.

Performance and Reflow Costs in Production Applications

In massive data tables or infinitely scrolling feeds containing hundreds of elements, grid-auto-flow: dense can cause measurable layout thrashing during DOM reconciliation. Because the browser must restart its cell-collision calculations at (1, 1) for every unplaced node, time complexity approaches quadratic proportions relative to the number of overflowing elements. To maintain 60 FPS scrolling and smooth micro-interactions:

  • Combine auto-flow with fixed column templates (e.g., repeat(4, minmax(0, 1fr))) rather than auto-fill with complex min-content rules.
  • Virtualize large list views using windowing techniques so that the CSS Grid calculation only operates on elements currently inside or adjacent to the viewport.
  • Utilize contain: layout on the grid container element to prevent local placement recalculations from triggering full-page reflow cascades.

Zero-Tracking Client-Side Computation

Our CSS Grid Auto-Flow Playground operates completely within your local browser environment. All track math, CSS generation, and DOM node simulations occur client-side without transmitting proprietary layout specifications, company data, or component telemetry to external cloud servers.

📐 Production Layout Takeaway

When building dashboards with varying card sizes (1x1, 2x1, 2x2), default to grid-auto-flow: row dense to eliminate dead space. Pair each configuration with a named profile and save it to your local History Log to quickly compare dense backfilling behaviors across responsive breakpoints.