DEV Community

Alex Chen
Alex Chen

Posted on

CSS Grid: Complete Guide to Modern Layouts

CSS Grid: Complete Guide to Modern Layouts

Grid is the most powerful CSS layout system. Once you learn it, you'll never go back.

Why Grid?

Before Grid:
- Floats (hacky, fragile)
- Flexbox (1D only — rows OR columns)
- Tables (not semantic)
- Absolute positioning (breaks easily)
- Bootstrap grid (lots of markup)

After Grid:
- 2D layout (rows AND columns simultaneously)
- Clean semantic HTML
- No extra wrapper divs
- Responsive without media queries (sometimes)
- Align things that were impossible before
Enter fullscreen mode Exit fullscreen mode

The Basics

<div class="grid-container">
  <div class="header">Header</div>
  <div class="sidebar">Sidebar</div>
  <div class="main">Main Content</div>
  <div class="footer">Footer</div>
</div>
Enter fullscreen mode Exit fullscreen mode
.grid-container {
  display: grid;

  /* Define columns: 3 columns */
  grid-template-columns: 200px 1fr 200px;
  /* Column 1: 200px fixed | Column 2: fills remaining space | Column 3: 200px fixed */

  /* Define rows: 4 rows */
  grid-template-rows: auto 1fr auto 80px;
  /* Row 1: content height | Row 2: fills space | Row 3: content height | Row 4: 80px fixed */

  gap: 20px;            /* Gap between all items (row + column) */
  row-gap: 10px;        /* Row gap only */
  column-gap: 15px;     /* Column gap only */
}
Enter fullscreen mode Exit fullscreen mode

The fr Unit (Fraction)

/* fr = "fraction of available space" */

grid-template-columns: 1fr 1fr 1fr;
/* Three equal columns */

grid-template-columns: 2fr 1fr;
/* First column is twice as wide as second */

grid-template-columns: 200px 1fr 200px;
/* Fixed - Flexible - Fixed */

grid-template-columns: repeat(3, 1fr);
/* Same as 1fr 1fr 1fr but cleaner */

grid-template-columns: minmax(200px, 1fr) minmax(200px, 1fr);
/* Each column: minimum 200px, then share remaining equally */

grid-template-columns: fit-content(300px) fit-content(300px);
/* Columns size to their content, max 300px */
Enter fullscreen mode Exit fullscreen mode

Placing Items

.item {
  /* Place in specific column/row */
  grid-column: 2;           /* Start at column 2 */
  grid-column: 1 / 3;      /* Span from col 1 to col 3 (covers 2 cols) */
  grid-row: 1 / span 2;    /* Row 1, spans 2 rows */

  /* Shorthand */
  grid-area: 1 / 2 / 3 / 4;  /* row-start / col-start / row-end / col-end */
}

/* Named areas (my favorite feature!) */
.layout {
  display: grid;
  grid-template-columns: 200px 1fr;
  grid-template-rows: auto 1fr auto;
  gap: 16px;
  grid-template-areas:
    "header header"
    "sidebar main"
    "footer footer";
}

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

/* Visual layout matches the ASCII art! Change layout by rearranging template-areas */
Enter fullscreen mode Exit fullscreen mode

Alignment & Justification

.grid {
  display: grid;
  grid-template-columns: repeat(3, 100px);
  grid-template-rows: repeat(3, 100px);
  height: 400px;

  /* Align items WITHIN their cells */
  align-items: start;     /* Top of cell */
  align-items: center;   /* Center vertically */
  align-items: end;       /* Bottom of cell */
  align-items: stretch;   /* Fill entire cell (default) */

  /* Justify items WITHIN their cells */
  justify-items: start;   /* Left of cell */
  justify-items: center; /* Center horizontally */
  justify-items: end;     /* Right of cell */
  justify-items: stretch; /* Fill entire cell (default) */

  /* Place items: shorthand for align-items + justify-items */
  place-items: center center; /* Both vertical + horizontal center */

  /* Align ENTIRE grid within container */
  align-content: start;    /* Pack rows to top */
  align-content: center;   /* Center rows vertically */
  align-content: end;      /* Pack rows to bottom */
  align-content: space-between; /* Space between rows */
  align-content: space-around;   /* Space around each row */
  align-content: space-evenly;   /* Equal spacing everywhere */

  /* Justify ENTIRE grid within container */
  justify-content: start;
  justify-content: center;
  justify-content: end;
  justify-content: space-between;

  /* Place entire grid: shorthand */
  place-content: center center;
}

/* Per-item alignment (overrides container defaults) */
.specific-item {
  align-self: center;
  justify-self: end;
  place-self: center start;
}
Enter fullscreen mode Exit fullscreen mode

Auto-Fit & Auto-Fill (Responsive Without Media Queries!)

/* auto-fill: Create as many columns as will fit */
.grid-auto-fill {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
  gap: 16px;
  /* Result: As many 250px+ columns as fit in the container.
     When window shrinks, columns drop to next line automatically! */
}

/* auto-fit: Like fill but empty tracks collapse */
.grid-auto-fit {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
  gap: 16px;
  /* Similar but existing items expand to fill space when there are
     fewer items than columns */
}

/* Practical card layout */
.card-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap: 24px;
}
/* On 1400px screen → 5 cards per row
   On 1000px screen → 3 cards per row
   On 600px screen  → 1 card per row
   All with ONE line of CSS! */
Enter fullscreen mode Exit fullscreen mode

Implicit Grid

.grid {
  display: grid;
  grid-template-columns: 1fr 1fr;  /* Only 2 explicit columns */
  grid-auto-rows: 150px;          /* Height for implicitly created rows */
  grid-auto-flow: row;             /* Place new items in new rows (default) */
  /* or */
  grid-auto-flow: column;         /* Place new items in new columns */
  grid-auto-columns: 100px;       /* Width for implicit columns */
}

/* When you have more items than defined cells,
   Grid creates implicit rows/columns automatically.
   These properties control those implicit cells. */
Enter fullscreen mode Exit fullscreen mode

Subgrid (The New Game Changer!)

/* Child grid can inherit parent's track definitions! */
.parent {
  display: grid;
  grid-template-columns: 200px 1fr 200px;
  gap: 16px;
}

.child-with-subgrid {
  display: grid;
  grid-template-columns: subgrid;  /* Inherits parent's columns! */
  grid-template-rows: subgrid;     /* Inherits parent's rows! */
  grid-column: span 3;            /* Span all 3 parent columns */
  gap: inherit;
}

/* Before Subgrid: Nested grids didn't align with parent grid lines.
   After Subgrid: Perfect alignment between nested and parent grids.
   Essential for complex layouts like card components inside a grid. */
Enter fullscreen mode Exit fullscreen mode

Common Layout Patterns

Holy Grail Layout

.holy-grail {
  display: grid;
  grid-template: 
    "header header header" auto
    "sidebar main   aside" 1fr
    "footer footer footer" 80px
    / 200px 1fr 200px;
  gap: 16px;
  min-height: 100vh;
}

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

@media (max-width: 768px) {
  .holy-grail {
    grid-template:
      "header"
      "main"
      "sidebar"
      "aside"
      "footer"
      / 1fr;
  }
}
Enter fullscreen mode Exit fullscreen mode

Dashboard Grid

.dashboard {
  display: grid;
  grid-template-columns: repeat(12, 1fr);  /* 12-column system */
  grid-template-rows: auto 1fr auto;
  gap: 16px;
  padding: 16px;
  min-height: 100vh;
}

.dash-header { grid-area: 1 / 1 / 2 / 13; }         /* Full width */
.dash-sidebar { grid-area: 2 / 1 / 3 / 3; }       /* Col 1-2, rows 2-3 */
.dash-main { grid-area: 2 / 3 / 3 / 11; }        /* Col 3-10, rows 2-3 */
.dash-right { grid-area: 2 / 11 / 3 / 13; }      /* Col 11-12, rows 2-3 */
.dash-footer { grid-area: 3 / 1 / 4 / 13; }       /* Full width */
Enter fullscreen mode Exit fullscreen mode

Gallery/Masonry-like

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

.gallery-item:nth-child(3n+1) { grid-row: span 2; }  /* Every 3rd item is taller */
.gallery-item:nth-child(5n) { grid-column: span 2; }  /* Every 5th item is wider */
Enter fullscreen mode Exit fullscreen mode

Quick Reference Card

Property What It Does
display: grid Enable grid layout
grid-template-columns Define column sizes
grid-template-rows Define row sizes
gap Space between items
grid-area Name/place an item
grid-template-areas Visual layout with names
align-items Vertical align in cells
justify-items Horizontal align in cells
place-items Shorthand align + justify
auto-fill/auto-fit Responsive columns
minmax(min, max) Flexible sizing range
subgrid Inherit parent tracks

Are you using Grid yet? What's your favorite pattern?

Follow @armorbreak for more frontend content.

Top comments (0)