Skip to article content

Mastering CSS Grid

CSS Grid is not just a layout tool — it is a two-dimensional layout system that fundamentally changes how we think about page structure. Unlike Flexbox (which excels at one-dimensional alignment), Grid gives us explicit control over rows and columns simultaneously.

Grid vs Flexbox: Different Tools, Same Page

A common misconception is that Grid replaces Flexbox. They serve different purposes and work beautifully together. Grid handles macro layout (page structure, card grids, dashboards), while Flexbox handles micro alignment (centering content within a card, spacing nav links).

/* Grid for page layout */
.page {
  display: grid;
  grid-template-columns: 1fr 300px;
  grid-template-areas:
    "header header"
    "main   sidebar"
    "footer footer";
  gap: 2rem;
}

/* Flexbox for component alignment */
.nav-links {
  display: flex;
  align-items: center;
  gap: 1.5rem;
}

The Power of Grid Template Areas

Named grid areas make layouts readable. Instead of counting column numbers, you describe the layout visually in your CSS. This is particularly powerful for responsive design — you can rearrange entire page sections by redefining the template areas at different breakpoints.

/* Desktop: sidebar on right */
@media (min-width: 768px) {
  .layout {
    grid-template-areas:
      "main sidebar";
  }
}

/* Mobile: stack vertically */
@media (max-width: 767px) {
  .layout {
    grid-template-areas:
      "main"
      "sidebar";
  }
}

Auto-Placement and minmax()

The auto-fill and auto-fit keywords with minmax() create responsive grids without any media queries. The browser calculates how many columns fit at the specified minimum width and distributes remaining space.

/* Responsive grid with no media queries */
.card-grid {
  display: grid;
  grid-template-columns: repeat(
    auto-fit, 
    minmax(280px, 1fr)
  );
  gap: 1.5rem;
}

The difference between auto-fill and auto-fit: auto-fill creates empty tracks when there is extra space, while auto-fit collapses empty tracks, allowing items to stretch wider.

Subgrid: The Missing Piece

Subgrid (now supported in all major browsers) allows child elements to inherit the parent grid's track sizing. This solves the longstanding problem of aligning content across sibling grid items.

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

.card {
  display: grid;
  grid-template-rows: subgrid;
  grid-row: span 3; /* header, body, footer */
}

Practical Patterns

The Holy Grail Layout

Header, footer, main content, and two sidebars — implemented in 5 lines of Grid code that is fully responsive:

.holy-grail {
  display: grid;
  grid-template: auto 1fr auto / 200px 1fr 200px;
  min-height: 100vh;
}
.header { grid-column: 1 / -1; }
.footer { grid-column: 1 / -1; }

Masonry-Style Layout

While native CSS masonry is still experimental, you can approximate it with dense auto-placement and varying row spans:

.masonry {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  grid-auto-rows: 100px;
  grid-auto-flow: dense;
}
.item-tall { grid-row: span 2; }
.item-wide { grid-column: span 2; }

Performance Considerations

Grid layout is calculated by the browser's layout engine and is extremely performant. However, avoid triggering unnecessary reflows by animating grid properties. Prefer animating transforms and opacity on grid items rather than changing their grid placement.

CSS Grid is declarative layout at its best. Describe what you want, let the browser figure out how to make it work across screen sizes. The fewer media queries you need, the better your grid code is.