DEV Community

Alex Chen
Alex Chen

Posted on

CSS Grid: Complete Guide to Modern Layouts

CSS Grid: Complete Guide to Modern Layouts

Flexbox is for 1D. Grid is for 2D. Here's how to master it.

Grid vs Flexbox: When to Use Which

Need to lay out items in ONE direction?
→ Use Flexbox (row OR column)

Need to lay out items in TWO directions (rows AND columns)?
→ Use Grid
Enter fullscreen mode Exit fullscreen mode

The Basics

.container {
  display: grid;
}
Enter fullscreen mode Exit fullscreen mode

Defining Columns and Rows

/* Fixed columns */
.grid { display: grid; grid-template-columns: 200px 200px 200px; }

/* Fractional units (equal width) */
.grid { display: grid; grid-template-columns: 1fr 1fr 1fr; }

/* Mixed */
.grid { display: grid; grid-template-columns: 250px 1fr 150px; }
/* Sidebar | Main content | Side panel */

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

/* auto-fit with minmax (responsive!) */
.grid { 
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
}

/* Rows */
.grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: auto auto auto; /* Or let it figure out */
}
Enter fullscreen mode Exit fullscreen mode

Gap

.grid {
  gap: 1rem;         /* Row + column gap */
  row-gap: 0.5rem;   /* Gap between rows */
  column-gap: 1rem;  /* Gap between columns */
}
Enter fullscreen mode Exit fullscreen mode

Placement

Named Areas (The Cleanest Approach)

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

.header { grid-area: header; }
.sidebar { grid-area: sidebar; }
.main { grid-area: main; }
.aside { grid-area: aside; }
.footer { grid-area: footer; }
Enter fullscreen mode Exit fullscreen mode

Line-Based Placement

.item {
  /* Start at column line 2, end at column line 4 */
  grid-column: 2 / 4;

  /* Start at row line 1, end at row line 3 */
  grid-row: 1 / 3;

  /* Span 2 columns */
  grid-column: span 2;

  /* Specific lines */
  grid-column-start: 1;
  grid-column-end: -1; /* Last line */
}
Enter fullscreen mode Exit fullscreen mode

Alignment

.container {
  /* Align all items in their cells */
  justify-items: start | center | end | stretch; /* Horizontal within cell */
  align-items: start | center | end | stretch;   /* Vertical within cell */

  /* Align the entire grid within container */
  justify-content: start | center | end | space-between | space-around | space-evenly;
  align-content: start | center | end | space-between | space-around | space-evenly;
}

/* Per-item override */
.specific-item {
  justify-self: center;
  align-self: end;
}
Enter fullscreen mode Exit fullscreen mode

Common Layouts

Dashboard Grid

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

.dashboard .widget {
  padding: 1.5rem;
  border-radius: 8px;
  background: white;
  box-shadow: 0 1px 3px rgba(0,0,0,0.1);
}

/* Full-width widget */
.widget.wide { grid-column: span 2; }
Enter fullscreen mode Exit fullscreen mode

Photo Gallery (Masonry-like)

.gallery {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  grid-auto-rows: 200px; /* Default height */
  gap: 8px;
}

.gallery .photo:nth-child(4n+1) { grid-row: span 2; } /* Tall photos */
.gallery img { width: 100%; height: 100%; object-fit: cover; }
Enter fullscreen mode Exit fullscreen mode

Responsive Card Grid

.cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: 1.5rem;
}

/* Auto-fits as many 300px+ columns as will fit */
/* On mobile: 1 column, tablet: 2 columns, desktop: 3-4 columns */
Enter fullscreen mode Exit fullscreen mode

Form Layout

.form-grid {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 1rem 0.5rem;
  align-items: center;
  max-width: 500px;
}

.form-grid label { font-weight: 600; }
.form-grid input, .form-grid select, .form-grid textarea {
  grid-column: 2;
}

.form-grid .full-width { grid-column: 1 / -1; }
Enter fullscreen mode Exit fullscreen mode

Implicit Grid (Auto-placement)

.container {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  /* Items automatically fill cells left-to-right, top-to-bottom */
}

/* Control implicit rows */
.container {
  grid-auto-rows: 200px;     /* All implicit rows = 200px */
  grid-auto-rows: minmax(100px, auto); /* At least 100px, grow if needed */
}

/* Change flow direction */
.container {
  grid-auto-flow: column;    /* Fill columns first, then rows */
  grid-auto-flow: dense;     /* Fill gaps (items may reorder) */
}
Enter fullscreen mode Exit fullscreen mode

Subgrid (Nesting)

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

.child {
  /* Child's grid aligns with parent's grid! */
  display: grid;
  grid-template-columns: subgrid;
  grid-template-rows: subgrid;
  gap: inherit;
}
Enter fullscreen mode Exit fullscreen mode

Quick Reference

Property Values Use Case
grid-template-columns repeat(n, fr) Define column structure
grid-template-rows auto / px / fr Define row structure
grid-template-areas "a b c" Named layout template
gap length Spacing
grid-column span N / start/end Item placement horizontal
grid-row span N / start/end Item placement vertical
justify-items start/center/end/stretch Item alignment in cell (H)
align-items start/center/end/stretch Item alignment in cell (V)
place-items shorthand Both alignments
auto-fit with minmax() Responsive columns

What's your favorite Grid layout trick?

Follow @armorbreak for more CSS content.

Top comments (0)