Skip to main content
HTML & CSS Foundations·Lesson 4 of 5

CSS Grid

CSS Grid is a two-dimensional layout system that handles both rows and columns simultaneously. While Flexbox is great for one-direction flow, Grid shines when you need precise control over a full page or component layout.

Basic Grid

Apply display: grid and define columns:

.grid {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  gap: 1rem;
}
<div class="grid">
  <div>1</div>
  <div>2</div>
  <div>3</div>
  <div>4</div>
  <div>5</div>
  <div>6</div>
</div>

This creates a 3-column grid. Items flow left-to-right, wrapping to new rows automatically. The fr unit distributes available space proportionally — three 1fr columns each get one-third.

Defining Rows and Columns

.layout {
  display: grid;
  grid-template-columns: 250px 1fr;       /* fixed sidebar + fluid main */
  grid-template-rows: auto 1fr auto;      /* header + content + footer */
  min-height: 100dvh;
}

You can mix units freely:

UnitBehavior
1frTakes a fraction of remaining space
200pxFixed pixel width
autoSizes to content
minmax(200px, 1fr)At least 200px, grows up to 1fr

The repeat() function

Instead of writing 1fr 1fr 1fr 1fr, use repeat():

.grid {
  /* 4 equal columns */
  grid-template-columns: repeat(4, 1fr);

  /* Pattern: small, large, small, large */
  grid-template-columns: repeat(2, 100px 1fr);
}

Grid Template Areas

Named areas let you define layouts visually in CSS:

.page {
  display: grid;
  grid-template-columns: 250px 1fr;
  grid-template-rows: auto 1fr auto;
  grid-template-areas:
    "header  header"
    "sidebar main"
    "footer  footer";
  min-height: 100dvh;
}

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

The grid-template-areas property maps directly to how the layout looks. Each string is a row, and each word is a column. Use . for empty cells:

grid-template-areas:
  "header header"
  ".      main"
  "footer footer";

Placing Items

Place items on specific grid lines using grid-column and grid-row:

.hero {
  grid-column: 1 / -1;  /* span all columns (1 to last line) */
}

.sidebar {
  grid-column: 1 / 2;   /* first column */
  grid-row: 2 / 4;       /* span rows 2 and 3 */
}

.featured {
  grid-column: span 2;  /* span 2 columns from current position */
}

Line numbers start at 1. Negative numbers count from the end, so -1 is the last line.

Auto-Flow and Implicit Grids

When items overflow the explicit grid, CSS creates implicit rows or columns:

.gallery {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-auto-rows: 200px;  /* implicit rows are 200px tall */
  gap: 1rem;
}

Change the flow direction with grid-auto-flow:

.horizontal {
  display: grid;
  grid-auto-flow: column;            /* items flow into new columns */
  grid-template-rows: repeat(3, 1fr); /* 3 rows defined */
  grid-auto-columns: 200px;           /* implicit columns are 200px */
}

Responsive Grids Without Media Queries

The most powerful Grid technique is auto-fitting columns that adapt to available space:

.auto-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
  gap: 1rem;
}

This creates as many 250px-minimum columns as fit. As the viewport shrinks, columns drop to new rows. No media queries needed.

  • auto-fill — creates as many tracks as fit, even if empty.
  • auto-fit — same, but collapses empty tracks so items can stretch wider.
/* auto-fit: 2 items stretch to fill a wide container */
.stretch-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
  gap: 1rem;
}

Alignment in Grid

Grid supports the same alignment properties as Flexbox, plus a few extras:

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

  /* Align all items */
  justify-items: center;  /* horizontal alignment within cells */
  align-items: center;    /* vertical alignment within cells */

  /* Align the grid itself within its container */
  justify-content: center;
  align-content: center;
}

/* Override for a single item */
.special {
  justify-self: end;
  align-self: start;
}

Common Grid Patterns

Dashboard layout

.dashboard {
  display: grid;
  grid-template-columns: 240px 1fr;
  grid-template-rows: 60px 1fr;
  grid-template-areas:
    "nav header"
    "nav content";
  min-height: 100dvh;
}
.card-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 1.5rem;
}

.card-grid .featured {
  grid-column: span 2;
  grid-row: span 2;
}

Holy grail layout

.holy-grail {
  display: grid;
  grid-template: auto 1fr auto / 200px 1fr 200px;
  grid-template-areas:
    "header header  header"
    "left   content right"
    "footer footer  footer";
  min-height: 100dvh;
}