HC

CSS Grid

HTML & CSS · 10 entries

Grid Container Basics

syntax
display: grid;
grid-template-columns: values;
grid-template-rows: values;
example
.layout {
  display: grid;
  grid-template-columns: 250px 1fr;
  grid-template-rows: auto 1fr auto;
  min-height: 100vh;
}

Note display: grid turns direct children into grid items. Unlike flexbox, grid controls both columns and rows simultaneously, making it ideal for two-dimensional layouts.

Fractional Unit (fr)

syntax
grid-template-columns: 1fr 2fr 1fr;
example
/* Three columns: 25% / 50% / 25% */
.layout {
  display: grid;
  grid-template-columns: 1fr 2fr 1fr;
  gap: 24px;
}

/* Fixed sidebar + flexible main */
.page {
  display: grid;
  grid-template-columns: 300px 1fr;
}

Note The fr unit distributes remaining free space proportionally. 1fr 2fr 1fr means the middle column gets twice the space of the side columns. Fixed sizes (px, rem) are allocated first, then fr units share what is left.

Repeat Function

syntax
grid-template-columns: repeat(count, size);
example
/* 4 equal columns */
.grid-4 {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 16px;
}

/* Pattern: 100px then 1fr, repeated 3 times */
.dashboard {
  grid-template-columns: repeat(3, 100px 1fr);
}

Note repeat() avoids writing the same value many times. You can repeat patterns too: repeat(3, 1fr 2fr) produces six columns alternating between 1fr and 2fr.

Auto-Fill & Auto-Fit

syntax
grid-template-columns: repeat(auto-fill, minmax(min, max));
grid-template-columns: repeat(auto-fit, minmax(min, max));
example
/* Cards that auto-wrap, minimum 280px each */
.card-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 24px;
}

Note auto-fill creates as many tracks as fit, leaving empty tracks if there are fewer items. auto-fit collapses empty tracks, letting items stretch to fill the row. For most card grids, auto-fit is what you want.

Minmax Function

syntax
minmax(minimum, maximum)
example
.layout {
  display: grid;
  grid-template-columns: minmax(200px, 300px) 1fr minmax(200px, 300px);
}

/* Sidebar that shrinks on small screens */
.page {
  grid-template-columns: minmax(150px, 250px) 1fr;
}

Note minmax() sets a size range for grid tracks. Common pattern: minmax(0, 1fr) prevents grid blowout when content is wider than the column. The default minimum for fr units is min-content, not 0.

Named Grid Areas

syntax
grid-template-areas:
  "header  header"
  "sidebar main"
  "footer  footer";
grid-area: name;
example
.page {
  display: grid;
  grid-template-columns: 250px 1fr;
  grid-template-rows: auto 1fr auto;
  grid-template-areas:
    "header  header"
    "sidebar content"
    "footer  footer";
  min-height: 100vh;
}

.page-header  { grid-area: header; }
.page-sidebar { grid-area: sidebar; }
.page-content { grid-area: content; }
.page-footer  { grid-area: footer; }

Note Named areas provide a visual map of your layout right in the CSS. Use a period (.) for empty cells. Each area name must form a rectangle. Changing the template in a media query rearranges the entire layout.

Grid Placement & Spanning

syntax
grid-column: start / end;
grid-row: start / end;
grid-column: span n;
example
.feature-card {
  grid-column: 1 / 3; /* spans columns 1 and 2 */
}

.tall-card {
  grid-row: span 2; /* spans 2 rows */
}

.full-width {
  grid-column: 1 / -1; /* spans all columns */
}

Note Grid lines are numbered starting at 1. Negative numbers count from the end (-1 is the last line). span n is a shorthand that avoids hardcoding line numbers.

Grid Gap

syntax
gap: row-gap column-gap;
row-gap: value;
column-gap: value;
example
.grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 24px;
}

.asymmetric {
  row-gap: 32px;
  column-gap: 16px;
}

Note The gap property works identically in grid and flexbox. It replaces the older grid-gap property. Gap only creates space between items, never on the outer edges.

Grid Alignment

syntax
justify-items: start | center | end | stretch;
align-items: start | center | end | stretch;
place-items: align justify;
example
.grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  place-items: center; /* center in both axes */
}

/* Individual item */
.special-item {
  justify-self: end;
  align-self: start;
}

Note In grid, justify controls the inline (horizontal) axis and align controls the block (vertical) axis. place-items is shorthand for both. Unlike flexbox, grid supports justify-self for individual items.

Subgrid

syntax
grid-template-columns: subgrid;
grid-template-rows: subgrid;
example
.card-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 24px;
}

.card {
  display: grid;
  grid-template-rows: subgrid;
  grid-row: span 3; /* participate in 3 parent rows */
}

/* Now all card titles, bodies, and footers align across cards */

Note Subgrid lets a nested grid item inherit its parent's track sizing. This is essential for aligning content across sibling cards (like matching title heights). The child must span the relevant parent tracks.