CSS Grid

Two-dimensional layouts with rows and columns

What is CSS Grid?

CSS Grid is a powerful two-dimensional layout system that allows you to create complex layouts with both rows and columns simultaneously. Unlike Flexbox, which is one-dimensional (either row or column), Grid gives you precise control over both axes at once.

Grid is layout-first: you define the structure, then place items into it. This makes it perfect for page layouts, dashboards, and any design where you need precise control over both dimensions.

Basic Grid Structure

Create a grid by setting display: grid and defining columns and rows:

Simple 3-Column Grid

1
2
3
4
5
6
.grid {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  gap: 16px;
}

Fractional Units (fr)

The fr unit represents a fraction of available space. It's Grid's most powerful sizing tool:

Equal Columns: 1fr 1fr 1fr

1fr
1fr
1fr

Each column gets equal space (33.33% each)

Unequal: 2fr 1fr 1fr

2fr (50%)
1fr (25%)
1fr (25%)

First column is twice as wide

Fixed + Flexible: 200px 1fr 1fr

200px
1fr
1fr

Fixed sidebar + flexible content

Repeat Notation

Save typing with repeat():

1
2
3
4
/* Instead of: 1fr 1fr 1fr 1fr */
grid-template-columns: repeat(4, 1fr);

/* Can repeat patterns */
grid-template-columns: repeat(3, 100px 200px);

Auto-Fit and Auto-Fill (Responsive Grids)

Create responsive grids without media queries using auto-fit or auto-fill:

Auto-Fit: Expands to Fill Space

Card 1
Card 2
Card 3
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
/* Cards are at least 250px, grow to fill space */
/* Reduces columns as screen shrinks */

Auto-Fill: Keeps Ghost Columns

grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
/* Creates extra empty columns if space available */
/* Use auto-fit for most cases */

Grid Item Placement

Place items precisely using grid lines (which are numbered starting at 1):

Spans 2 columns
1x1
Spans 2 rows
span 2
/* By line numbers (start / end) */
.wide { grid-column: 1 / 3; }        /* From line 1 to 3 */
.tall { grid-row: 1 / 3; }           /* From line 1 to 3 */

/* Using span */
.span-two { grid-column: span 2; }   /* Span 2 columns */

/* Full width */
.full { grid-column: 1 / -1; }       /* First to last line */

Grid Template Areas

The most intuitive way to create complex layouts—name your areas and place them visually:

Header
Sidebar
Main Content
Footer
.container {
  display: grid;
  grid-template-columns: 200px 1fr 1fr;
  grid-template-rows: auto 1fr auto;
  grid-template-areas:
    "header  header  header"
    "sidebar main    main"
    "footer  footer  footer";
  gap: 16px;
  min-height: 100vh;
}

.header  { grid-area: header; }
.sidebar { grid-area: sidebar; }
.main    { grid-area: main; }
.footer  { grid-area: footer; }

Gap (Gutters)

Control spacing between grid items:

gap: 20px

gap: 20px;

row-gap + column-gap

row-gap: 20px;
column-gap: 8px;

Alignment in Grid

Grid has powerful alignment options for both the grid container and individual items:

justify-items / align-items (align all items)

Centered
in
cells
justify-items: start | center | end | stretch;
align-items: start | center | end | stretch;
place-items: center;  /* shorthand */

justify-self / align-self (align one item)

.item {
  justify-self: center;  /* horizontal in cell */
  align-self: center;    /* vertical in cell */
  place-self: center;    /* shorthand */
}

Real-World Layouts

Dashboard Layout

Nav
Header
Stats
Chart 1
Chart 2
.dashboard {
  display: grid;
  grid-template-columns: 250px 1fr 1fr;
  grid-template-rows: auto auto 1fr;
  grid-template-areas:
    "sidebar header  header"
    "sidebar stats   stats"
    "sidebar chart1  chart2";
  gap: 20px;
  height: 100vh;
}

Responsive Card Grid (No Media Queries!)

Card
Card
Card
Card
.cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: 24px;
}
/* Automatically creates as many columns as fit! */

Magazine Layout

Featured
Story
Story
Story
Story
Story
.gallery {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  grid-auto-rows: 200px;
  gap: 10px;
}
.featured { grid-column: span 2; grid-row: span 2; }
.wide { grid-column: span 2; }

⚠️ Common Grid Gotchas

  • Grid lines vs tracks: 3 columns = 4 grid lines (1, 2, 3, 4)
  • fr units and min-content: 1fr won't shrink below min-content. Use minmax(0, 1fr) to allow it
  • Overflow: Grid items can overflow their cells. Use min-width: 0 on items to allow shrinking
  • IE11 support: Grid works in IE11 but with limited features and -ms- prefix

✓ Grid Cheat Sheet

Container Properties:

Item Properties:

  • grid-column: start / end
  • grid-row: start / end
  • grid-area: name
  • justify-self / align-self