|

CSS 20 💻 grid-auto-columns, grid-auto-rows and grid-auto-flow properties

These three properties control how auto-placed grid items are sized and positioned. They’re essential for handling grids where the number of items isn’t known in advance or where you want automatic sizing rules.


Overview of Properties

PropertyDescription
grid-auto-columnsSets the default size for auto-placed columns
grid-auto-rowsSets the default size for auto-placed rows
grid-auto-flowControls how auto-placed items flow into the grid

1. grid-auto-columns

The grid-auto-columns property defines the default size for auto-placed columns — columns that are created implicitly when items are placed outside the explicitly defined grid.

.grid-container {
    display: grid;
    grid-template-rows: 50px auto 70px;
    grid-auto-columns: 200px;
}

What happens:

  • The grid has 3 explicit rows
  • No explicit columns are defined
  • Items are auto-placed, creating implicit columns
  • Each implicit column is 200px wide

Values

ValueDescriptionExample
lengthFixed size (px, cm, em)grid-auto-columns: 200px;
percentagePercentage of containergrid-auto-columns: 25%;
frFraction of available spacegrid-auto-columns: 1fr;
minmax(min, max)Min and max dimensionsgrid-auto-columns: minmax(100px, 1fr);
min-contentMinimum possible spacegrid-auto-columns: min-content;
max-contentMaximum possible spacegrid-auto-columns: max-content;
fit-contentFits content within limitsgrid-auto-columns: fit-content(200px);
autoAutomatic sizinggrid-auto-columns: auto;

Important: This property only applies to auto-placed items, not to items that are explicitly positioned.


2. grid-auto-rows

The grid-auto-rows property defines the default size for auto-placed rows — rows that are created implicitly when items are placed outside the explicitly defined grid.

.grid-container-rows {
    display: grid;
    grid-template-columns: 200px auto;
    grid-auto-rows: 50px;
}

What happens:

  • The grid has 2 explicit columns
  • No explicit rows are defined
  • Items are auto-placed, creating implicit rows
  • Each implicit row is 50px tall

Values

Same as grid-auto-columns:
length, percentage, fr, minmax(), min-content, max-content, fit-content(), auto


3. grid-auto-flow

The grid-auto-flow property specifies how auto-placed items are placed in the grid.

.grid-container-flow {
    display: grid;
    grid-template-rows: repeat(3, 50px);
    grid-template-columns: repeat(2, 200px);
    grid-auto-flow: row dense;
}

Values

ValueDescription
rowItems fill rows first (default)
columnItems fill columns first
row denseFills rows, and “dense” packs items to fill holes
column denseFills columns, and “dense” packs items to fill holes

row vs column

grid-auto-flow: row (default):

Item 1  Item 2  Item 3
Item 4  Item 5  Item 6

grid-auto-flow: column:

Item 1  Item 3  Item 5
Item 2  Item 4  Item 6

The dense Keyword

The dense keyword tells the grid to fill in holes left by items that span multiple tracks. Without dense, gaps may remain.

Without dense:

┌─────┬─────┬─────┐
│  1  │  2  │  3  │
├─────┼─────┴─────┤
│  4  │    5      │
├─────┼─────┬─────┤
│  6  │     │     │
└─────┴─────┴─────┘
   ↑ gap remains

With dense:

┌─────┬─────┬─────┐
│  1  │  2  │  3  │
├─────┼─────┴─────┤
│  4  │    5      │
├─────┼─────┬─────┤
│  6  │  7  │  8  │
└─────┴─────┴─────┘
   ↑ holes filled

Note: dense can change the visual order of items, which may affect accessibility. Use it carefully.


Complete Example

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>grid-auto-columns, grid-auto-rows, grid-auto-flow</title>
    <style>
        *, *::before, *::after {
            box-sizing: border-box;
        }

        body {
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
            max-width: 1200px;
            margin: 0 auto;
            padding: 20px;
            background: #f8f9fa;
            line-height: 1.6;
        }

        h1 {
            color: #007bff;
            border-bottom: 3px solid #007bff;
            padding-bottom: 10px;
        }

        h2 {
            color: #28a745;
            border-left: 4px solid #28a745;
            padding-left: 15px;
            margin-top: 30px;
        }

        h3 {
            color: #333;
            margin-top: 20px;
        }

        section {
            background: white;
            padding: 20px;
            border-radius: 8px;
            box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
            margin: 20px 0;
        }

        .code-block {
            background: #1e1e1e;
            color: #d4d4d4;
            padding: 15px;
            border-radius: 8px;
            overflow-x: auto;
            font-family: 'Courier New', monospace;
            font-size: 0.9rem;
            line-height: 1.8;
            margin: 10px 0;
        }

        .reference-table {
            width: 100%;
            border-collapse: collapse;
            margin: 15px 0;
        }

        .reference-table th,
        .reference-table td {
            padding: 10px;
            border: 1px solid #ddd;
            text-align: left;
        }

        .reference-table th {
            background: #007bff;
            color: white;
        }

        .reference-table tr:nth-child(even) {
            background: #f8f9fa;
        }

        /* ====== GRID DEMOS ====== */
        .cell {
            border: 2px solid #333;
            padding: 15px;
            border-radius: 4px;
            font-weight: bold;
            text-align: center;
            display: flex;
            align-items: center;
            justify-content: center;
            background: #007bff;
            color: white;
        }

        .cell:nth-child(even) {
            background: #28a745;
        }

        .cell:nth-child(3n) {
            background: #dc3545;
        }

        /* grid-auto-columns demo */
        .grid-auto-cols {
            display: grid;
            grid-template-rows: 50px auto 70px;
            grid-auto-columns: 200px;
            gap: 10px;
            padding: 10px;
            background: #e9ecef;
            border-radius: 8px;
            margin: 15px 0;
        }

        /* grid-auto-rows demo */
        .grid-auto-rows {
            display: grid;
            grid-template-columns: 200px auto;
            grid-auto-rows: 50px;
            gap: 10px;
            padding: 10px;
            background: #e9ecef;
            border-radius: 8px;
            margin: 15px 0;
        }

        /* grid-auto-flow: row */
        .grid-flow-row {
            display: grid;
            grid-template-rows: repeat(3, 50px);
            grid-template-columns: repeat(3, 1fr);
            grid-auto-flow: row;
            gap: 10px;
            padding: 10px;
            background: #e9ecef;
            border-radius: 8px;
            margin: 15px 0;
        }

        /* grid-auto-flow: column */
        .grid-flow-column {
            display: grid;
            grid-template-rows: repeat(3, 50px);
            grid-template-columns: repeat(3, 1fr);
            grid-auto-flow: column;
            gap: 10px;
            padding: 10px;
            background: #e9ecef;
            border-radius: 8px;
            margin: 15px 0;
        }

        /* grid-auto-flow: row dense */
        .grid-flow-dense {
            display: grid;
            grid-template-rows: repeat(3, 60px);
            grid-template-columns: repeat(3, 1fr);
            grid-auto-flow: row dense;
            gap: 10px;
            padding: 10px;
            background: #e9ecef;
            border-radius: 8px;
            margin: 15px 0;
        }

        .grid-flow-dense .span-2 {
            grid-column: span 2;
        }

        .grid-flow-dense .span-3 {
            grid-column: span 3;
        }

        /* Non-dense for comparison */
        .grid-flow-no-dense {
            display: grid;
            grid-template-rows: repeat(3, 60px);
            grid-template-columns: repeat(3, 1fr);
            grid-auto-flow: row;
            gap: 10px;
            padding: 10px;
            background: #e9ecef;
            border-radius: 8px;
            margin: 15px 0;
        }

        .grid-flow-no-dense .span-2 {
            grid-column: span 2;
        }

        .grid-flow-no-dense .span-3 {
            grid-column: span 3;
        }

        .note {
            font-size: 0.9rem;
            color: #6c757d;
            margin-top: 5px;
        }

        .highlight {
            background: #ffc107;
            color: #333;
            padding: 2px 6px;
            border-radius: 4px;
            font-weight: bold;
        }
    </style>
</head>
<body>

    <h1>grid-auto-columns, grid-auto-rows, and grid-auto-flow</h1>

    <!-- ====== 1. GRID-AUTO-COLUMNS ====== -->
    <section>
        <h2>1. grid-auto-columns</h2>
        <p>Defines the default size for <strong>auto-placed columns</strong>. Only one explicit property is set: <code>grid-template-rows</code>.</p>

        <div class="grid-auto-cols">
            <div class="cell">Item 1</div>
            <div class="cell">Item 2</div>
            <div class="cell">Item 3</div>
            <div class="cell">Item 4</div>
            <div class="cell">Item 5</div>
            <div class="cell">Item 6</div>
        </div>

        <p class="note">Each auto-created column is <span class="highlight">200px</span> wide.</p>

        <div class="code-block">
            .grid-auto-cols {
                display: grid;
                grid-template-rows: 50px auto 70px;
                grid-auto-columns: 200px;
                gap: 10px;
            }
        </div>
    </section>

    <!-- ====== 2. GRID-AUTO-ROWS ====== -->
    <section>
        <h2>2. grid-auto-rows</h2>
        <p>Defines the default size for <strong>auto-placed rows</strong>. Only one explicit property is set: <code>grid-template-columns</code>.</p>

        <div class="grid-auto-rows">
            <div class="cell">Item 1</div>
            <div class="cell">Item 2</div>
            <div class="cell">Item 3</div>
            <div class="cell">Item 4</div>
            <div class="cell">Item 5</div>
            <div class="cell">Item 6</div>
        </div>

        <p class="note">Each auto-created row is <span class="highlight">50px</span> tall.</p>

        <div class="code-block">
            .grid-auto-rows {
                display: grid;
                grid-template-columns: 200px auto;
                grid-auto-rows: 50px;
                gap: 10px;
            }
        </div>
    </section>

    <!-- ====== 3. GRID-AUTO-FLOW: ROW ====== -->
    <section>
        <h2>3. grid-auto-flow: row (default)</h2>
        <p>Items fill <strong>rows first</strong>, then wrap to the next row.</p>

        <div class="grid-flow-row">
            <div class="cell">1</div>
            <div class="cell">2</div>
            <div class="cell">3</div>
            <div class="cell">4</div>
            <div class="cell">5</div>
            <div class="cell">6</div>
        </div>

        <div class="code-block">
            .grid-flow-row {
                display: grid;
                grid-template-rows: repeat(3, 50px);
                grid-template-columns: repeat(3, 1fr);
                grid-auto-flow: row;  /* Default */
                gap: 10px;
            }
        </div>
    </section>

    <!-- ====== 4. GRID-AUTO-FLOW: COLUMN ====== -->
    <section>
        <h2>4. grid-auto-flow: column</h2>
        <p>Items fill <strong>columns first</strong>, then wrap to the next column.</p>

        <div class="grid-flow-column">
            <div class="cell">1</div>
            <div class="cell">2</div>
            <div class="cell">3</div>
            <div class="cell">4</div>
            <div class="cell">5</div>
            <div class="cell">6</div>
        </div>

        <div class="code-block">
            .grid-flow-column {
                display: grid;
                grid-template-rows: repeat(3, 50px);
                grid-template-columns: repeat(3, 1fr);
                grid-auto-flow: column;  /* Fills columns first */
                gap: 10px;
            }
        </div>
    </section>

    <!-- ====== 5. GRID-AUTO-FLOW: DENSE ====== -->
    <section>
        <h2>5. grid-auto-flow: row dense</h2>
        <p>When items span multiple tracks, <code>dense</code> fills in the gaps left behind.</p>

        <h3>Without dense (gaps remain):</h3>
        <div class="grid-flow-no-dense">
            <div class="cell span-2">1 (span 2)</div>
            <div class="cell">2</div>
            <div class="cell">3</div>
            <div class="cell span-3">4 (span 3)</div>
            <div class="cell">5</div>
            <div class="cell">6</div>
        </div>
        <p class="note">Gap remains in the first row because item 3 doesn't fit.</p>

        <h3>With dense (gaps filled):</h3>
        <div class="grid-flow-dense">
            <div class="cell span-2">1 (span 2)</div>
            <div class="cell">2</div>
            <div class="cell">3</div>
            <div class="cell span-3">4 (span 3)</div>
            <div class="cell">5</div>
            <div class="cell">6</div>
        </div>
        <p class="note">Item 3 moves up to fill the gap, making the grid more compact.</p>

        <div class="code-block">
            /* Without dense — gaps may remain */
            .grid {
                grid-auto-flow: row;
            }

            /* With dense — fills in holes */
            .grid {
                grid-auto-flow: row dense;
            }

            /* Column dense */
            .grid {
                grid-auto-flow: column dense;
            }
        </div>
    </section>

    <!-- ====== 6. COMPARISON: ROW vs COLUMN ====== -->
    <section>
        <h2>6. Side-by-Side Comparison</h2>

        <div style="display: grid; grid-template-columns: 1fr 1fr; gap: 30px;">
            <div>
                <h4>grid-auto-flow: row</h4>
                <div class="grid-flow-row" style="grid-template-rows: repeat(2, 50px); grid-template-columns: repeat(3, 1fr);">
                    <div class="cell">1</div>
                    <div class="cell">2</div>
                    <div class="cell">3</div>
                    <div class="cell">4</div>
                    <div class="cell">5</div>
                    <div class="cell">6</div>
                </div>
                <p class="note">Order: 1, 2, 3, 4, 5, 6 (left to right, top to bottom)</p>
            </div>

            <div>
                <h4>grid-auto-flow: column</h4>
                <div class="grid-flow-column" style="grid-template-rows: repeat(2, 50px); grid-template-columns: repeat(3, 1fr);">
                    <div class="cell">1</div>
                    <div class="cell">2</div>
                    <div class="cell">3</div>
                    <div class="cell">4</div>
                    <div class="cell">5</div>
                    <div class="cell">6</div>
                </div>
                <p class="note">Order: 1, 2, 3, 4, 5, 6 (top to bottom, left to right)</p>
            </div>
        </div>
    </section>

    <!-- ====== 7. REFERENCE TABLES ====== -->
    <section>
        <h2>7. Reference Tables</h2>

        <h3>Auto Properties</h3>
        <table class="reference-table">
            <tr>
                <th>Property</th>
                <th>Description</th>
                <th>Example</th>
            </tr>
            <tr>
                <td><code>grid-auto-columns</code></td>
                <td>Default size for auto-placed columns</td>
                <td><code>grid-auto-columns: 200px;</code></td>
            </tr>
            <tr>
                <td><code>grid-auto-rows</code></td>
                <td>Default size for auto-placed rows</td>
                <td><code>grid-auto-rows: 50px;</code></td>
            </tr>
            <tr>
                <td><code>grid-auto-flow</code></td>
                <td>How auto-placed items flow</td>
                <td><code>grid-auto-flow: row dense;</code></td>
            </tr>
        </table>

        <h3>grid-auto-flow Values</h3>
        <table class="reference-table">
            <tr>
                <th>Value</th>
                <th>Description</th>
            </tr>
            <tr>
                <td><code>row</code></td>
                <td>Items fill rows first (default)</td>
            </tr>
            <tr>
                <td><code>column</code></td>
                <td>Items fill columns first</td>
            </tr>
            <tr>
                <td><code>row dense</code></td>
                <td>Fills rows and packs items to fill holes</td>
            </tr>
            <tr>
                <td><code>column dense</code></td>
                <td>Fills columns and packs items to fill holes</td>
            </tr>
        </table>

        <h3>Values for grid-auto-columns and grid-auto-rows</h3>
        <table class="reference-table">
            <tr>
                <th>Value</th>
                <th>Description</th>
                <th>Example</th>
            </tr>
            <tr>
                <td><code>length</code></td>
                <td>Fixed size (px, cm, em)</td>
                <td><code>200px</code></td>
            </tr>
            <tr>
                <td><code>percentage</code></td>
                <td>Percentage of container</td>
                <td><code>25%</code></td>
            </tr>
            <tr>
                <td><code>fr</code></td>
                <td>Fraction of available space</td>
                <td><code>1fr</code></td>
            </tr>
            <tr>
                <td><code>minmax(min, max)</code></td>
                <td>Min and max dimensions</td>
                <td><code>minmax(100px, 1fr)</code></td>
            </tr>
            <tr>
                <td><code>min-content</code></td>
                <td>Minimum possible space</td>
                <td><code>min-content</code></td>
            </tr>
            <tr>
                <td><code>max-content</code></td>
                <td>Maximum possible space</td>
                <td><code>max-content</code></td>
            </tr>
            <tr>
                <td><code>fit-content(limit)</code></td>
                <td>Fits content within limits</td>
                <td><code>fit-content(200px)</code></td>
            </tr>
            <tr>
                <td><code>auto</code></td>
                <td>Automatic sizing</td>
                <td><code>auto</code></td>
            </tr>
        </table>
    </section>

    <!-- ====== 8. BEST PRACTICES ====== -->
    <section>
        <h2>8. Best Practices</h2>

        <div style="background: #d4edda; padding: 20px; border-radius: 8px; border-left: 4px solid #28a745;">
            <h3 style="margin-top: 0; color: #155724;">✅ Do This:</h3>
            <ul>
                <li>Use <code>grid-auto-rows</code> to control the height of auto-created rows</li>
                <li>Use <code>grid-auto-columns</code> to control the width of auto-created columns</li>
                <li>Use <code>grid-auto-flow: row dense</code> to fill gaps in complex layouts</li>
                <li>Use <code>grid-auto-flow: column</code> for vertical layouts (e.g., navigation)</li>
                <li>Test with different content sizes to ensure the grid behaves as expected</li>
            </ul>
        </div>

        <div style="background: #f8d7da; padding: 20px; border-radius: 8px; border-left: 4px solid #dc3545; margin-top: 15px;">
            <h3 style="margin-top: 0; color: #721c24;">❌ Don't Do This:</h3>
            <ul>
                <li>Don't use <code>grid-auto-columns</code> when you've defined all columns explicitly</li>
                <li>Don't use <code>dense</code> without considering the visual order change</li>
                <li>Don't forget that <code>grid-auto-flow</code> only affects <strong>auto-placed</strong> items</li>
                <li>Don't rely solely on <code>dense</code> for accessibility — visual order should match DOM order when possible</li>
            </ul>
        </div>
    </section>

</body>
</html>

Quick Reference

PropertyDescriptionExample
grid-auto-columnsDefault size for auto-placed columnsgrid-auto-columns: 200px;
grid-auto-rowsDefault size for auto-placed rowsgrid-auto-rows: 50px;
grid-auto-flowHow auto-placed items flowgrid-auto-flow: row dense;

grid-auto-flow Values

ValueDescription
rowItems fill rows first (default)
columnItems fill columns first
row denseFills rows and packs items to fill holes
column denseFills columns and packs items to fill holes

Best Practices

Do This:

/* Control the height of auto-created rows */
.grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    grid-auto-rows: 100px; /* Each auto row is 100px */
}

/* Fill gaps with dense */
.grid {
    grid-auto-flow: row dense;
}

/* Vertical layout with column flow */
.nav {
    display: grid;
    grid-auto-flow: column;
    gap: 10px;
}

Don’t Do This:

/* Don't use auto-columns when columns are defined */
.grid {
    grid-template-columns: 1fr 1fr;
    grid-auto-columns: 200px; /* Only affects extra columns */
}

/* Don't use dense without understanding the trade-offs */
.grid {
    grid-auto-flow: dense; /* Can change visual order */
}

Pro Tip: grid-auto-rows and grid-auto-columns are essential when you don’t know how many items your grid will contain (e.g., dynamic content from a database). Use grid-auto-flow: row dense to compact your grid and fill holes — but be aware that dense can change the visual order of items, which may confuse users relying on screen readers. Always test your grid with different content sizes!


Stop using slow, ad-bloated tool sites! 🤮

🔎 Search “KandZ Tools” on Google to use many professional utilities for free.

KandZ.me is the ultimate minimalist hub for:
✅ Finance (Mortgage, Interest, Inflation)
✅ Tech (Base64, JSON, Dev Suite, IP)
✅ Health (BMI, BMR, TDEE)
✅ Productivity (Timer, Workspace, QR)

⚡️ Fast & Private
🔒 No data leaves your device
💎 100% Free

🔗 Use it now: https://tools.kandz.me
🔖 Bookmark it—you’ll need it later!