CSS Grid Layout

CSS Grid Layout

CSS Grid Layout is a powerful two-dimensional layout system that allows you to create complex, responsive layouts with ease. This tutorial covers everything you need to know about CSS Grid.

What is CSS Grid?

CSS Grid is a layout system that provides rows and columns, making it easier to design complex web layouts without using floats or positioning. Unlike Flexbox (which is one-dimensional), Grid works in two dimensions simultaneously.

Basic Grid Concepts

1. Grid Container and Items

.container {
  display: grid; /* This makes it a grid container */
}

.item {
  /* These are grid items */
}
<div class="container">
  <div class="item">Item 1</div>
  <div class="item">Item 2</div>
  <div class="item">Item 3</div>
</div>

Grid Container Properties

1. Defining Grid Structure

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

2. Using fr Units

The fr unit represents a fraction of available space.

.container {
  display: grid;
  grid-template-columns: 1fr 2fr 1fr; /* 1:2:1 ratio */
  grid-template-rows: auto 1fr auto;   /* Auto height, flexible middle */
}

3. repeat() Function

Simplify repetitive track definitions.

.container {
  display: grid;
  grid-template-columns: repeat(3, 1fr); /* Same as 1fr 1fr 1fr */
  grid-template-rows: repeat(2, 100px);   /* Two rows of 100px each */
}

4. minmax() Function

Define minimum and maximum track sizes.

.container {
  display: grid;
  grid-template-columns: minmax(200px, 1fr) minmax(200px, 1fr);
  grid-template-rows: minmax(100px, auto);
}

5. auto-fill and auto-fit

Create responsive grids that adapt to container size.

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

Grid Gap and Spacing

1. gap Property

Add space between grid items.

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

/* Or specify separately */
.container {
  grid-row-gap: 20px;    /* Gap between rows */
  grid-column-gap: 10px;  /* Gap between columns */
}

Grid Item Placement

1. Grid Lines

Grid items are placed between grid lines.

.container {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  grid-template-rows: repeat(3, 100px);
}

.item1 {
  grid-column-start: 1;
  grid-column-end: 3;
  grid-row-start: 1;
  grid-row-end: 2;
}

/* Shorthand */
.item2 {
  grid-column: 3 / 5;  /* From line 3 to line 5 */
  grid-row: 1 / 3;     /* From line 1 to line 3 */
}

2. span Keyword

Span multiple tracks.

.item3 {
  grid-column: span 2;  /* Span 2 columns */
  grid-row: span 1;      /* Span 1 row */
}

.item4 {
  grid-column: 2 / span 3;  /* Start at column 2, span 3 columns */
}

3. grid-area Property

Define all four lines at once.

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

Grid Template Areas

1. Named Grid Areas

Create visual layout templates.

.container {
  display: grid;
  grid-template-columns: 1fr 3fr 1fr;
  grid-template-rows: auto 1fr auto;
  grid-template-areas:
    "header header header"
    "sidebar main aside"
    "footer footer footer";
  gap: 20px;
}

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

Practical Grid Examples

1. Holy Grail Layout

Classic web layout with header, footer, and three columns.

.holy-grail {
  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: 1rem;
}

.header { grid-area: header; background: #333; color: white; padding: 1rem; }
.nav { grid-area: nav; background: #f4f4f4; padding: 1rem; }
.main { grid-area: main; background: white; padding: 1rem; }
.aside { grid-area: aside; background: #f4f4f4; padding: 1rem; }
.footer { grid-area: footer; background: #333; color: white; padding: 1rem; }
<div class="holy-grail">
  <header class="header">Header</header>
  <nav class="nav">Navigation</nav>
  <main class="main">Main Content</main>
  <aside class="aside">Sidebar</aside>
  <footer class="footer">Footer</footer>
</div>

2. Card Grid

Responsive grid of cards.

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

.card {
  background: white;
  border-radius: 8px;
  box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
  overflow: hidden;
  transition: transform 0.3s ease;
}

.card:hover {
  transform: translateY(-5px);
}

.card-image {
  width: 100%;
  height: 200px;
  object-fit: cover;
}

.card-content {
  padding: 1.5rem;
}

.card-title {
  font-size: 1.5rem;
  margin-bottom: 0.5rem;
}

.card-text {
  color: #666;
  line-height: 1.6;
}
<div class="card-grid">
  <div class="card">
    <img src="image1.jpg" alt="Card 1" class="card-image">
    <div class="card-content">
      <h3 class="card-title">Card Title 1</h3>
      <p class="card-text">This is the content for card 1.</p>
    </div>
  </div>
  <div class="card">
    <img src="image2.jpg" alt="Card 2" class="card-image">
    <div class="card-content">
      <h3 class="card-title">Card Title 2</h3>
      <p class="card-text">This is the content for card 2.</p>
    </div>
  </div>
  <div class="card">
    <img src="image3.jpg" alt="Card 3" class="card-image">
    <div class="card-content">
      <h3 class="card-title">Card Title 3</h3>
      <p class="card-text">This is the content for card 3.</p>
    </div>
  </div>
</div>

3. Dashboard Layout

Complex dashboard with multiple sections.

.dashboard {
  display: grid;
  grid-template-columns: 250px 1fr 300px;
  grid-template-rows: 60px 1fr 40px;
  grid-template-areas:
    "sidebar header header"
    "sidebar main widgets"
    "sidebar footer footer";
  height: 100vh;
  gap: 1px;
  background: #e0e0e0;
}

.header {
  grid-area: header;
  background: white;
  display: flex;
  align-items: center;
  padding: 0 2rem;
  border-bottom: 1px solid #ddd;
}

.sidebar {
  grid-area: sidebar;
  background: #2c3e50;
  color: white;
  padding: 1rem;
}

.main {
  grid-area: main;
  background: white;
  padding: 2rem;
  overflow-y: auto;
}

.widgets {
  grid-area: widgets;
  background: #f8f9fa;
  padding: 1rem;
}

.footer {
  grid-area: footer;
  background: #34495e;
  color: white;
  display: flex;
  align-items: center;
  justify-content: center;
}

4. Image Gallery

Responsive image gallery with varying sizes.

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

.gallery-item {
  background: #ddd;
  border-radius: 4px;
  overflow: hidden;
}

.gallery-item img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* Featured items span multiple tracks */
.gallery-item.featured {
  grid-column: span 2;
  grid-row: span 2;
}

.gallery-item.wide {
  grid-column: span 2;
}

.gallery-item.tall {
  grid-row: span 2;
}
<div class="gallery">
  <div class="gallery-item featured">
    <img src="featured.jpg" alt="Featured image">
  </div>
  <div class="gallery-item">
    <img src="image1.jpg" alt="Gallery image 1">
  </div>
  <div class="gallery-item wide">
    <img src="wide.jpg" alt="Wide image">
  </div>
  <div class="gallery-item">
    <img src="image2.jpg" alt="Gallery image 2">
  </div>
  <div class="gallery-item tall">
    <img src="tall.jpg" alt="Tall image">
  </div>
  <div class="gallery-item">
    <img src="image3.jpg" alt="Gallery image 3">
  </div>
</div>

Advanced Grid Features

1. Auto-Placement

Control how grid items are automatically placed.

.container {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-auto-flow: row; /* Default: place in rows */
  grid-auto-flow: column; /* Place in columns */
  grid-auto-flow: dense; /* Fill gaps */
}

2. Implicit Grid

Define size for automatically created grid tracks.

.container {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-auto-rows: 100px;  /* Height of implicit rows */
  grid-auto-columns: 200px; /* Width of implicit columns */
}

3. Grid Alignment

Align grid items within their grid areas.

.container {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: repeat(3, 200px);
  justify-items: center;  /* Horizontal alignment of items */
  align-items: center;    /* Vertical alignment of items */
  place-items: center;    /* Both alignments at once */
}

/* Individual item alignment */
.item {
  justify-self: start;  /* Align this item to start */
  align-self: end;     /* Align this item to end */
  place-self: center;  /* Center this item */
}

4. Grid Container Alignment

Align the grid itself within its container.

.container {
  display: grid;
  grid-template-columns: repeat(2, 200px);
  grid-template-rows: repeat(2, 150px);
  width: 800px;
  height: 600px;
  justify-content: center;  /* Horizontal alignment of grid */
  align-content: center;    /* Vertical alignment of grid */
  place-content: center;    /* Center grid */
}

Responsive Grid Design

1. Media Queries with Grid

Adapt grid layouts for different screen sizes.

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

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

/* Desktop */
@media (min-width: 1024px) {
  .responsive-grid {
    grid-template-columns: repeat(4, 1fr);
  }
}

/* Large desktop */
@media (min-width: 1440px) {
  .responsive-grid {
    grid-template-columns: repeat(6, 1fr);
  }
}

2. Container Queries

Modern approach for component-level responsiveness.

@container (min-width: 400px) {
  .card-grid {
    grid-template-columns: repeat(2, 1fr);
  }
}

@container (min-width: 800px) {
  .card-grid {
    grid-template-columns: repeat(3, 1fr);
  }
}

Grid vs Flexbox

When to Use Grid:

  • Two-dimensional layouts (rows AND columns)
  • Complex page layouts
  • Aligning items in both dimensions
  • Overlapping elements

When to Use Flexbox:

  • One-dimensional layouts (rows OR columns)
  • Component-level layouts
  • Content distribution
  • Navigation bars

Combining Grid and Flexbox:

/* Grid for overall layout */
.page-layout {
  display: grid;
  grid-template-areas:
    "header header"
    "sidebar main"
    "footer footer";
}

/* Flexbox for component layout */
.navigation {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

Browser Support

CSS Grid is supported in all modern browsers:

  • Chrome 57+
  • Firefox 52+
  • Safari 10.1+
  • Edge 16+
  • Internet Explorer 11 (with limited support and prefix)

Feature Detection:

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

/* Fallback for older browsers */
@supports not (display: grid) {
  .container {
    display: flex;
    flex-wrap: wrap;
  }
  .container > * {
    flex: 1 1 300px;
    margin: 10px;
  }
}

Best Practices

1. Mobile-First Approach

.grid {
  display: grid;
  gap: 1rem;
  grid-template-columns: 1fr; /* Single column on mobile */
}

@media (min-width: 768px) {
  .grid {
    grid-template-columns: repeat(2, 1fr);
  }
}

@media (min-width: 1024px) {
  .grid {
    grid-template-columns: repeat(3, 1fr);
  }
}

2. Use Semantic HTML

<div class="grid-container">
  <header class="header">Header</header>
  <nav class="nav">Navigation</nav>
  <main class="main">Main Content</main>
  <aside class="aside">Sidebar</aside>
  <footer class="footer">Footer</footer>
</div>

3. Accessibility Considerations

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

/* Ensure content remains readable */
@media (prefers-reduced-motion: reduce) {
  .grid-item {
    transition: none;
  }
}

Complete Example

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>CSS Grid Example</title>
  <style>
    * {
      margin: 0;
      padding: 0;
      box-sizing: border-box;
    }

    body {
      font-family: Arial, sans-serif;
      line-height: 1.6;
      color: #333;
    }

    .page-container {
      display: grid;
      grid-template-areas:
        "header header"
        "nav main"
        "footer footer";
      grid-template-columns: 200px 1fr;
      grid-template-rows: auto 1fr auto;
      min-height: 100vh;
      gap: 1px;
      background: #ddd;
    }

    .header {
      grid-area: header;
      background: #2c3e50;
      color: white;
      padding: 1rem;
      display: flex;
      justify-content: space-between;
      align-items: center;
    }

    .nav {
      grid-area: nav;
      background: #34495e;
      color: white;
      padding: 1rem;
    }

    .nav ul {
      list-style: none;
    }

    .nav li {
      margin-bottom: 0.5rem;
    }

    .nav a {
      color: white;
      text-decoration: none;
      display: block;
      padding: 0.5rem;
      border-radius: 4px;
      transition: background 0.3s ease;
    }

    .nav a:hover {
      background: #4a5f7a;
    }

    .main {
      grid-area: main;
      background: white;
      padding: 2rem;
    }

    .content-grid {
      display: grid;
      grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
      gap: 2rem;
      margin-top: 2rem;
    }

    .card {
      background: #f8f9fa;
      border-radius: 8px;
      padding: 1.5rem;
      box-shadow: 0 2px 4px rgba(0,0,0,0.1);
    }

    .card h3 {
      margin-bottom: 1rem;
      color: #2c3e50;
    }

    .footer {
      grid-area: footer;
      background: #2c3e50;
      color: white;
      text-align: center;
      padding: 1rem;
    }

    /* Responsive adjustments */
    @media (max-width: 768px) {
      .page-container {
        grid-template-areas:
          "header"
          "nav"
          "main"
          "footer";
        grid-template-columns: 1fr;
      }

      .nav {
        text-align: center;
      }

      .nav ul {
        display: flex;
        justify-content: center;
        flex-wrap: wrap;
      }

      .nav li {
        margin: 0.25rem;
      }
    }
  </style>
</head>
<body>
  <div class="page-container">
    <header class="header">
      <h1>My Website</h1>
      <div class="header-nav">
        <a href="#">Home</a>
        <a href="#">About</a>
        <a href="#">Contact</a>
      </div>
    </header>

    <nav class="nav">
      <ul>
        <li><a href="#">Dashboard</a></li>
        <li><a href="#">Profile</a></li>
        <li><a href="#">Settings</a></li>
        <li><a href="#">Help</a></li>
      </ul>
    </nav>

    <main class="main">
      <h2>Main Content</h2>
      <p>This is the main content area using CSS Grid for layout.</p>
      
      <div class="content-grid">
        <div class="card">
          <h3>Feature 1</h3>
          <p>Description of the first feature in our grid layout.</p>
        </div>
        <div class="card">
          <h3>Feature 2</h3>
          <p>Description of the second feature in our grid layout.</p>
        </div>
        <div class="card">
          <h3>Feature 3</h3>
          <p>Description of the third feature in our grid layout.</p>
        </div>
      </div>
    </main>

    <footer class="footer">
      <p>&copy; 2024 My Website. All rights reserved.</p>
    </footer>
  </div>
</body>
</html>

External Resources:

Related Tutorials:

Last updated on