CSS Grid Layout - Complete Guide

CSS Grid is a powerful two-dimensional layout system that makes creating complex web layouts simple and maintainable. This guide covers everything you need to master CSS Grid.

What is CSS Grid? #

CSS Grid Layout is a two-dimensional layout system for the web. It lets you lay out items in rows and columns simultaneously, making it perfect for creating complex responsive layouts.

Grid vs Flexbox #

FeatureGridFlexbox
DimensionTwo-dimensionalOne-dimensional
Use CaseComplex layoutsSimple layouts
ControlBoth axesSingle axis
AlignmentExcellentExcellent

Use Grid for page layouts, Flexbox for components.

Basic Grid Setup #

<div class="container">
  <div class="item">1</div>
  <div class="item">2</div>
  <div class="item">3</div>
  <div class="item">4</div>
</div>
.container {
  display: grid;
  grid-template-columns: 200px 200px 200px;
  grid-template-rows: 100px 100px;
  gap: 10px;
}

Container Properties #

display: grid #

.container {
  display: grid;  /* Block-level grid */
}

.inline-container {
  display: inline-grid;  /* Inline-level grid */
}

grid-template-columns #

Defines column tracks:

/* Fixed widths */
.container {
  grid-template-columns: 200px 300px 200px;
}

/* Fractional units (fr) */
.container {
  grid-template-columns: 1fr 2fr 1fr;  /* 1:2:1 ratio */
}

/* Mix units */
.container {
  grid-template-columns: 200px 1fr 20%;
}

/* repeat() */
.container {
  grid-template-columns: repeat(3, 1fr);  /* Three equal columns */
  grid-template-columns: repeat(4, 100px);
}

/* auto-fill */
.container {
  grid-template-columns: repeat(auto-fill, 200px);
}

/* auto-fit */
.container {
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
}

/* minmax() */
.container {
  grid-template-columns: minmax(200px, 1fr) 300px;
}

grid-template-rows #

Defines row tracks:

.container {
  grid-template-rows: 100px 200px 100px;
}

/* Auto rows */
.container {
  grid-template-rows: repeat(3, auto);
}

/* Mix with fr */
.container {
  grid-template-rows: 100px 1fr 100px;
}

grid-template-areas #

Named grid areas:

.container {
  grid-template-areas:
    "header header header"
    "sidebar main main"
    "footer footer footer";
}

.header {
  grid-area: header;
}

.sidebar {
  grid-area: sidebar;
}

.main {
  grid-area: main;
}

.footer {
  grid-area: footer;
}

gap (grid-gap) #

Space between grid items:

/* Both row and column */
.container {
  gap: 20px;
}

/* Separate row and column */
.container {
  row-gap: 20px;
  column-gap: 10px;
}

/* Shorthand */
.container {
  gap: 20px 10px;  /* row column */
}

justify-items #

Align items horizontally within their cell:

.container {
  justify-items: start;    /* Left */
  justify-items: center;   /* Center */
  justify-items: end;      /* Right */
  justify-items: stretch;  /* Default: fill cell */
}

align-items #

Align items vertically within their cell:

.container {
  align-items: start;      /* Top */
  align-items: center;     /* Center */
  align-items: end;        /* Bottom */
  align-items: stretch;    /* Default: fill cell */
}

place-items #

Shorthand for align-items and justify-items:

.container {
  place-items: center;  /* Both axes */
  place-items: center start;  /* align-items justify-items */
}

justify-content #

Align entire grid horizontally:

.container {
  justify-content: start;
  justify-content: center;
  justify-content: end;
  justify-content: space-between;
  justify-content: space-around;
  justify-content: space-evenly;
}

align-content #

Align entire grid vertically:

.container {
  align-content: start;
  align-content: center;
  align-content: end;
  align-content: space-between;
  align-content: space-around;
  align-content: space-evenly;
}

place-content #

Shorthand for align-content and justify-content:

.container {
  place-content: center;
  place-content: space-between center;
}

Item Properties #

grid-column #

Specify column span:

/* Start and end lines */
.item {
  grid-column-start: 1;
  grid-column-end: 3;  /* Spans columns 1-2 */
}

/* Shorthand */
.item {
  grid-column: 1 / 3;
}

/* Span notation */
.item {
  grid-column: 1 / span 2;  /* Start at 1, span 2 columns */
}

/* Span from current */
.item {
  grid-column: span 2;
}

grid-row #

Specify row span:

/* Start and end lines */
.item {
  grid-row-start: 1;
  grid-row-end: 4;
}

/* Shorthand */
.item {
  grid-row: 1 / 4;
}

/* Span notation */
.item {
  grid-row: 2 / span 2;
}

grid-area #

Shorthand for row and column:

/* row-start / column-start / row-end / column-end */
.item {
  grid-area: 1 / 1 / 3 / 3;
}

/* Or use named areas */
.item {
  grid-area: header;
}

justify-self #

Override justify-items for single item:

.item {
  justify-self: start;
  justify-self: center;
  justify-self: end;
  justify-self: stretch;
}

align-self #

Override align-items for single item:

.item {
  align-self: start;
  align-self: center;
  align-self: end;
  align-self: stretch;
}

place-self #

Shorthand for align-self and justify-self:

.item {
  place-self: center;
  place-self: start end;
}

Common Layouts #

Equal Columns #

.container {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 20px;
}

Responsive Columns (Auto-Fit) #

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

Holy Grail Layout #

<div class="container">
  <header>Header</header>
  <nav>Nav</nav>
  <main>Main</main>
  <aside>Aside</aside>
  <footer>Footer</footer>
</div>
.container {
  display: grid;
  grid-template-columns: 200px 1fr 200px;
  grid-template-rows: auto 1fr auto;
  grid-template-areas:
    "header header header"
    "nav main aside"
    "footer footer footer";
  min-height: 100vh;
  gap: 10px;
}

header {
  grid-area: header;
}

nav {
  grid-area: nav;
}

main {
  grid-area: main;
}

aside {
  grid-area: aside;
}

footer {
  grid-area: footer;
}

Card Grid #

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

.card {
  border: 1px solid #ddd;
  padding: 20px;
}

Masonry-Style Grid #

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

.item {
  grid-row: span var(--row-span);
}

/* In HTML: style="--row-span: 20" */
.container {
  display: grid;
  grid-template-columns: 250px 1fr;
  gap: 20px;
  min-height: 100vh;
}

.sidebar {
  background: #f4f4f4;
}

.main {
  background: white;
}

Centered Content #

.container {
  display: grid;
  place-items: center;
  min-height: 100vh;
}

Overlapping Items #

.container {
  display: grid;
  grid-template-columns: 1fr;
  grid-template-rows: 1fr;
}

.item1, .item2 {
  grid-column: 1;
  grid-row: 1;
}

.item2 {
  z-index: 1;
  place-self: center;
}

Responsive Design #

Mobile First #

/* Mobile: Single column */
.container {
  display: grid;
  grid-template-columns: 1fr;
  gap: 10px;
}

/* Tablet: Two columns */
@media (min-width: 768px) {
  .container {
    grid-template-columns: repeat(2, 1fr);
    gap: 20px;
  }
}

/* Desktop: Three columns */
@media (min-width: 1024px) {
  .container {
    grid-template-columns: repeat(3, 1fr);
    gap: 30px;
  }
}

Auto-Responsive #

/* No media queries needed */
.container {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(300px, 100%), 1fr));
  gap: 20px;
}

Responsive Grid Areas #

.container {
  display: grid;
  gap: 10px;
}

/* Mobile */
.container {
  grid-template-areas:
    "header"
    "nav"
    "main"
    "aside"
    "footer";
}

/* Desktop */
@media (min-width: 768px) {
  .container {
    grid-template-columns: 200px 1fr 200px;
    grid-template-areas:
      "header header header"
      "nav main aside"
      "footer footer footer";
  }
}

Advanced Techniques #

Named Lines #

.container {
  display: grid;
  grid-template-columns: [sidebar-start] 200px [sidebar-end main-start] 1fr [main-end];
}

.sidebar {
  grid-column: sidebar-start / sidebar-end;
}

.main {
  grid-column: main-start / main-end;
}

Dense Grid #

.container {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(100px, 1fr));
  grid-auto-flow: dense;  /* Fill gaps */
}

Subgrid #

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

.child {
  display: grid;
  grid-template-columns: subgrid;  /* Inherit parent columns */
}

Grid Functions #

repeat() #

grid-template-columns: repeat(3, 1fr);
grid-template-columns: repeat(auto-fill, 200px);
grid-template-columns: repeat(3, 100px 200px);  /* Pattern */

minmax() #

grid-template-columns: minmax(200px, 400px) 1fr;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));

fit-content() #

grid-template-columns: fit-content(300px) 1fr;

min() and max() #

grid-template-columns: repeat(auto-fit, minmax(min(300px, 100%), 1fr));

Debugging Grid #

Browser DevTools #

All modern browsers have Grid debugging tools:

.container {
  display: grid;
}

/* In DevTools: Click "grid" badge to see grid overlay */

Visual Outline #

.container {
  display: grid;
  outline: 2px solid red;
}

.item {
  outline: 1px solid blue;
}

Browser Support #

CSS Grid is supported in all modern browsers:

  • Chrome 57+
  • Firefox 52+
  • Safari 10.1+
  • Edge 16+
  • IE 11 (partial, with -ms- prefix)

Best Practices #

  1. Use Grid for layouts, Flexbox for components
  2. Start with mobile-first design
  3. Use fr units for flexible columns
  4. Use gap instead of margins
  5. Name grid areas for clarity
  6. Use auto-fit/auto-fill for responsive grids
  7. Combine with Flexbox where appropriate
  8. Test across browsers
  9. Use DevTools for debugging
  10. Keep it simple - don’t overcomplicate

CSS Grid revolutionizes web layouts. Master these concepts and you can build any layout with ease and maintainability.