CSS Grid Complete Guide — grid-template, auto-fill, minmax, and Responsive Layouts

Complete CSS Grid guide: grid-template-columns, grid-template-rows, auto-fill, auto-fit, minmax, grid areas, and responsive layout patterns with zero media queries.

Introduction

CSS Grid is the most powerful layout system ever added to CSS. Unlike Flexbox (which is one-dimensional), Grid lets you control both rows and columns simultaneously. The result: complex magazine-style layouts, responsive card grids, and full-page application shells — all without a single media query in many cases. Browser support is now 97%+ worldwide, so there is no excuse not to use it.

The Basics — Defining a Grid

Any element becomes a grid container with display: grid. All direct children become grid items automatically.

.container {
    display: grid;

    /* Define 3 equal columns */
    grid-template-columns: 1fr 1fr 1fr;

    /* Or use repeat() shorthand */
    grid-template-columns: repeat(3, 1fr);

    /* Define row heights */
    grid-template-rows: auto 200px auto;

    /* Gap between cells */
    gap: 1rem;                /* row-gap + column-gap */
    row-gap: 1rem;
    column-gap: 2rem;
}

The fr unit is the key innovation: it distributes the remaining space after fixed/auto sizes are calculated. 1fr 2fr means the second column gets twice as much space as the first.

grid-template — The Shorthand

/* Rows / Columns */
.grid {
    grid-template: 100px auto 100px / 200px 1fr;
    /*             rows           /  columns   */
}

/* Using named areas */
.layout {
    grid-template:
        "header header header" 80px
        "sidebar main   aside" 1fr
        "footer  footer footer" 60px
        / 200px  1fr    200px;
}

Named Grid Areas — The Most Readable Pattern

.layout {
    display: grid;
    grid-template-areas:
        "header  header"
        "sidebar main"
        "footer  footer";
    grid-template-columns: 250px 1fr;
    grid-template-rows: 60px 1fr 60px;
    min-height: 100vh;
    gap: 1rem;
}

.header  { grid-area: header; }
.sidebar { grid-area: sidebar; }
.main    { grid-area: main; }
.footer  { grid-area: footer; }
<div class="layout">
    <header class="header">Header</header>
    <aside class="sidebar">Sidebar</aside>
    <main class="main">Main Content</main>
    <footer class="footer">Footer</footer>
</div>

auto-fill vs auto-fit — The Essential Difference

Both auto-fill and auto-fit create as many columns as will fit. The difference is subtle but important for responsive layouts:

/* auto-fill: creates empty columns to fill the row */
.grid-fill {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
    gap: 1rem;
}

/* auto-fit: collapses empty columns, items stretch to fill */
.grid-fit {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
    gap: 1rem;
}

Practical rule: use auto-fill when you want consistent column widths at any count; use auto-fit when you want items to stretch and fill the full row.

minmax() — The Responsive Superpower

minmax(min, max) sets the minimum and maximum size for a track. Combined with auto-fill, it creates fully responsive grids without media queries:

/* Responsive card grid — no media queries needed */
.cards {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
    gap: 1.5rem;
}
/* Result:
   - 4 columns on wide screens
   - 3 columns on medium screens
   - 2 columns on tablets
   - 1 column on mobile
   All automatic, zero @media */
/* Common minmax patterns */

/* Never less than 200px, can grow to fill */
grid-template-columns: repeat(3, minmax(200px, 1fr));

/* Auto rows: at least 100px, grows with content */
grid-auto-rows: minmax(100px, auto);

/* Fluid typography-aware columns */
grid-template-columns: repeat(auto-fill, minmax(min(300px, 100%), 1fr));

Placing Items Explicitly

/* Place by line numbers (1-indexed) */
.item {
    grid-column: 1 / 3;    /* start at line 1, end at line 3 */
    grid-row: 2 / 4;
}

/* Using span */
.item {
    grid-column: span 2;   /* span 2 columns from auto position */
    grid-row: 1 / span 3;  /* start at line 1, span 3 rows */
}

/* Shorthand: row-start / column-start / row-end / column-end */
.item {
    grid-area: 1 / 2 / 3 / 4;
}

/* Named lines */
.container {
    grid-template-columns: [start] 1fr [center] 1fr [end];
}
.item {
    grid-column: start / center;
}

Alignment in Grid

.container {
    /* Align all items within their cells */
    justify-items: center;   /* horizontal: start | end | center | stretch */
    align-items: center;     /* vertical:   start | end | center | stretch */
    place-items: center;     /* shorthand: align-items / justify-items */

    /* Align the grid tracks within the container */
    justify-content: space-between;  /* if grid narrower than container */
    align-content: start;
    place-content: center;
}

/* Override for individual items */
.item {
    justify-self: end;
    align-self: start;
    place-self: center end;
}

Real-World Patterns

Masonry-like Layout with auto-rows

.masonry {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
    grid-auto-rows: 10px;  /* small unit for fine control */
    gap: 10px;
}

/* Each item needs inline style: grid-row-end: span N */
/* Calculate N = ceil(itemHeight / rowHeight) */

Holy Grail Layout

.holy-grail {
    display: grid;
    grid-template:
        "header" auto
        "nav main aside" 1fr
        "footer" auto
        / 200px 1fr 200px;
    min-height: 100dvh;
}

.header { grid-area: header; }
.nav    { grid-area: nav; }
.main   { grid-area: main; }
.aside  { grid-area: aside; }
.footer { grid-area: footer; }

Responsive without Media Queries

/* Stack on mobile, side-by-side on desktop */
.two-col {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(400px, 100%), 1fr));
    gap: 2rem;
}

/* Feature grid: 1-3 columns based on space */
.features {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(250px, 100%), 1fr));
    gap: 1.5rem;
}

Subgrid — Next-Level Alignment

Subgrid (now in all major browsers) lets nested elements align to the parent grid:

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

.child {
    grid-column: span 3;
    display: grid;
    grid-template-columns: subgrid; /* inherits parent's 3 columns */
}

DevKits Tools for CSS Development

When building layouts, these DevKits tools save time:

Summary

CSS Grid has made responsive layout dramatically simpler. The key patterns to internalize:

  • repeat(auto-fill, minmax(250px, 1fr)) — the responsive grid one-liner
  • Named grid areas for complex page layouts
  • fr units for proportional space distribution
  • place-items: center for centering anything
  • Subgrid for nested alignment