DEV Community

Akash for MechCloud Academy

Posted on

CSS Grid vs Flexbox: An Extended Tutorial with Examples

CSS Grid and Flexbox are cornerstone layout systems in modern web design, each offering unique strengths for creating responsive and visually appealing interfaces. This extended tutorial dives deeper into their differences, explores additional use cases, provides more detailed examples, and includes advanced tips to help you master both technologies.

Overview

  • Flexbox: A one-dimensional layout system that excels at arranging items along a single axis (either a row or a column). It’s designed for flexibility, making it ideal for dynamic, content-driven layouts like navigation bars, forms, or card arrangements.
  • CSS Grid: A two-dimensional layout system that allows precise control over both rows and columns simultaneously. It’s perfect for structured, grid-based designs, such as full-page layouts or complex dashboards.

Key Differences

Feature Flexbox CSS Grid
Dimensions One-dimensional (row or column) Two-dimensional (rows and columns)
Use Case Linear layouts, dynamic content Complex layouts, fixed grid structures
Content vs Layout Content-driven (adapts to content size) Layout-driven (defines structure first)
Alignment Strong alignment control in one axis Precise alignment in both axes
Item Placement Limited control over item placement Precise placement with grid lines/areas
Gap Control Limited (uses margin or gap in modern browsers) Native gap property for rows and columns
Responsiveness Relies on wrapping and media queries Flexible with auto-fit, minmax, and media queries

When to Use

  • Use Flexbox for:
    • Aligning items in a single direction (e.g., navigation menus, button groups).
    • Dynamic content where item sizes vary (e.g., a list of cards with different content lengths).
    • Simple, responsive layouts with wrapping or equal-height items.
    • Centering content horizontally or vertically with minimal code.
  • Use CSS Grid for:
    • Full-page layouts with defined rows and columns (e.g., header, sidebar, main, footer).
    • Overlapping or precisely placed elements (e.g., magazine-style layouts).
    • Complex designs requiring explicit grid structures (e.g., dashboards, photo galleries).
    • Layouts where you need equal spacing and alignment in both dimensions.

Deep Dive: Flexbox Properties

Flexbox offers a range of properties to control layout:

  • Container Properties:
    • display: flex: Defines a flex container.
    • flex-direction: row | column: Sets the main axis direction.
    • justify-content: Aligns items along the main axis (flex-start, center, space-between, etc.).
    • align-items: Aligns items along the cross axis (stretch, center, baseline, etc.).
    • flex-wrap: wrap | nowrap: Controls whether items wrap to a new line.
    • gap: Sets spacing between flex items (modern browsers).
  • Item Properties:
    • flex-grow: Defines how much an item grows relative to others.
    • flex-shrink: Defines how much an item shrinks.
    • flex-basis: Sets the initial size of an item.
    • order: Changes the visual order of items.

Deep Dive: CSS Grid Properties

CSS Grid provides extensive control over layout:

  • Container Properties:
    • display: grid: Defines a grid container.
    • grid-template-columns: Defines column sizes (e.g., 100px 1fr 2fr).
    • grid-template-rows: Defines row sizes.
    • grid-template-areas: Names grid areas for easy placement.
    • gap: Sets spacing between grid cells.
    • justify-items / align-items: Aligns items within cells.
    • grid-auto-flow: row | column: Controls how auto-placed items are arranged.
  • Item Properties:
    • grid-column: Specifies column placement (e.g., 1 / 3 spans columns 1 to 2).
    • grid-row: Specifies row placement.
    • grid-area: Assigns an item to a named area or specific position.
    • justify-self / align-self: Aligns an item within its cell.

Example 1: Flexbox Layout (Responsive Navigation Bar)

Flexbox is ideal for a navigation bar that adapts to different screen sizes, with items wrapping or stacking as needed.

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Flexbox Navigation Bar</title>
  <style>
    nav {
      display: flex;
      justify-content: space-between;
      align-items: center;
      background-color: #2c3e50;
      padding: 1rem;
      flex-wrap: wrap;
    }
    nav a {
      color: #ecf0f1;
      text-decoration: none;
      padding: 0.75rem 1.5rem;
      font-family: Arial, sans-serif;
      font-size: 1.1rem;
      transition: background-color 0.3s;
    }
    nav a:hover {
      background-color: #34495e;
      border-radius: 5px;
    }
    @media (max-width: 768px) {
      nav {
        flex-direction: column;
        align-items: flex-start;
      }
      nav a {
        margin: 0.5rem 0;
      }
    }
  </style>
</head>
<body>
  <nav>
    <a href="#">Home</a>
    <a href="#">About</a>
    <a href="#">Services</a>
    <a href="#">Portfolio</a>
    <a href="#">Contact</a>
  </nav>
</body>
</html>
Enter fullscreen mode Exit fullscreen mode

Explanation:

  • display: flex creates a flex container.
  • justify-content: space-between distributes items evenly along the horizontal axis.
  • align-items: center vertically centers items.
  • flex-wrap: wrap ensures items wrap on smaller screens.
  • Media query switches to flex-direction: column for mobile devices, stacking items vertically.
  • Hover effects and transitions enhance user interaction.

Example 2: CSS Grid Layout (Full Page Structure)

CSS Grid is perfect for a structured page layout with a header, sidebar, main content, and footer, with precise control over placement.

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>CSS Grid Page Layout</title>
  <style>
    body {
      margin: 0;
      font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
    }
    .container {
      display: grid;
      grid-template-columns: 250px 1fr;
      grid-template-rows: 80px 1fr 60px;
      gap: 15px;
      height: 100vh;
      grid-template-areas: 
        "header header"
        "sidebar main"
        "footer footer";
    }
    .header {
      grid-area: header;
      background-color: #2980b9;
      color: white;
      display: flex;
      align-items: center;
      padding: 0 2rem;
      font-size: 1.5rem;
    }
    .sidebar {
      grid-area: sidebar;
      background-color: #ecf0f1;
      padding: 1.5rem;
    }
    .main {
      grid-area: main;
      background-color: #f5f6fa;
      padding: 1.5rem;
    }
    .footer {
      grid-area: footer;
      background-color: #2c3e50;
      color: white;
      display: flex;
      align-items: center;
      justify-content: center;
    }
    @media (max-width: 768px) {
      .container {
        grid-template-columns: 1fr;
        grid-template-rows: auto;
        grid-template-areas: 
          "header"
          "sidebar"
          "main"
          "footer";
      }
    }
  </style>
</head>
<body>
  <div class="container">
    <div class="header">Website Header</div>
    <div class="sidebar">
      <h3>Sidebar</h3>
      <ul>
        <li><a href="#">Link 1</a></li>
        <li><a href="#">Link 2</a></li>
        <li><a href="#">Link 3</a></li>
      </ul>
    </div>
    <div class="main">
      <h2>Main Content</h2>
      <p>This is the main content area, where you can place articles, images, or other content.</p>
    </div>
    <div class="footer">© 2025 Your Website</div>
  </div>
</body>
</html>
Enter fullscreen mode Exit fullscreen mode

Explanation:

  • display: grid creates a grid container.
  • grid-template-columns: 250px 1fr defines a fixed sidebar and flexible main area.
  • grid-template-rows: 80px 1fr 60px sets heights for header, content, and footer.
  • grid-template-areas names sections for easy placement.
  • gap: 15px adds spacing between grid cells.
  • Media query stacks all sections vertically for smaller screens.
  • Flexbox is used within the header and footer for internal alignment.

Example 3: Combining Flexbox and CSS Grid (Card Gallery)

Combining Grid and Flexbox creates a responsive card gallery where Grid handles the overall layout, and Flexbox manages the internal structure of each card.

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Grid with Flexbox Cards</title>
  <style>
    body {
      margin: 0;
      font-family: 'Arial', sans-serif;
      background-color: #f4f4f4;
    }
    .container {
      display: grid;
      grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
      gap: 20px;
      padding: 20px;
      max-width: 1200px;
      margin: 0 auto;
    }
    .card {
      display: flex;
      flex-direction: column;
      background-color: white;
      border-radius: 8px;
      box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
      overflow: hidden;
    }
    .card img {
      width: 100%;
      height: 200px;
      object-fit: cover;
    }
    .card-content {
      flex-grow: 1;
      padding: 1.5rem;
    }
    .card-content h3 {
      margin: 0 0 0.5rem;
      font-size: 1.25rem;
    }
    .card-content p {
      margin: 0 0 1rem;
      color: #555;
    }
    .card button {
      background-color: #e74c3c;
      color: white;
      border: none;
      padding: 0.75rem;
      cursor: pointer;
      font-size: 1rem;
      margin: 0 1.5rem 1.5rem;
      border-radius: 5px;
      transition: background-color 0.3s;
    }
    .card button:hover {
      background-color: #c0392b;
    }
  </style>
</head>
<body>
  <div class="container">
    <div class="card">
      <img src="https://via.placeholder.com/300x200" alt="Placeholder">
      <div class="card-content">
        <h3>Card 1</h3>
        <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore.</p>
      </div>
      <button>Read More</button>
    </div>
    <div class="card">
      <img src="https://via.placeholder.com/300x200" alt="Placeholder">
      <div class="card-content">
        <h3>Card 2</h3>
        <p>Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo.</p>
      </div>
      <button>Read More</button>
    </div>
    <div class="card">
      <img src="https://via.placeholder.com/300x200" alt="Placeholder">
      <div class="card-content">
        <h3>Card 3</h3>
        <p>Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla.</p>
      </div>
      <button>Read More</button>
    </div>
    <div class="card">
      <img src="https://via.placeholder.com/300x200" alt="Placeholder">
      <div class="card-content">
        <h3>Card 4</h3>
        <p>Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim.</p>
      </div>
      <button>Read More</button>
    </div>
  </div>
</body>
</html>
Enter fullscreen mode Exit fullscreen mode

Explanation:

  • Grid (grid-template-columns: repeat(auto-fit, minmax(300px, 1fr))) creates a responsive grid that adjusts the number of columns based on screen size.
  • Each card uses Flexbox (display: flex; flex-direction: column) to stack image, content, and button vertically.
  • flex-grow: 1 ensures the content area expands to fill available space.
  • box-shadow and border-radius add visual polish to the cards.
  • The button includes a hover effect for interactivity.

Advanced Tips

  1. Flexbox:
    • Use flex: 1 as a shorthand for flex-grow: 1; flex-shrink: 1; flex-basis: 0% to make items grow and shrink equally.
    • Combine min-width: 0 with flex-shrink to prevent overflow in flex items with large content.
    • Use order to rearrange items without changing the HTML structure (e.g., for accessibility vs. visual order).
  2. CSS Grid:
    • Leverage minmax(0, 1fr) for responsive columns that don’t exceed their content’s size.
    • Use grid-template-areas for readable, maintainable layouts.
    • Combine auto-fit with minmax for dynamic, responsive grids without media queries.
    • Use fr units sparingly with fixed sizes (e.g., px) to balance flexibility and control.
  3. Combining Both:
    • Nest Flexbox inside Grid cells for fine-tuned item alignment (e.g., centering content in a grid cell).
    • Use Grid for the outer layout and Flexbox for inner components to reduce complexity.
    • Avoid over-nesting to maintain performance and readability.

Browser Support

  • Flexbox: Supported in all modern browsers (IE10+ with prefixes). Use vendor prefixes (-webkit-) for older browsers.
  • CSS Grid: Supported in all modern browsers (IE11+ with prefixes, limited features). Use @supports (display: grid) for fallback styles.

Performance Considerations

  • Flexbox: Lightweight for small layouts but can be slower with many items due to dynamic calculations.
  • CSS Grid: Efficient for complex layouts but may require more planning to avoid overlapping issues.
  • Best Practice: Minimize nested layouts and use browser dev tools to inspect rendering performance.

Debugging Tips

  • Flexbox:
    • Check flex-wrap if items aren’t wrapping as expected.
    • Ensure min-width or max-width isn’t preventing shrinking or growing.
    • Use outline to visualize flex item boundaries.
  • CSS Grid:
    • Enable the grid overlay in browser dev tools to inspect grid lines and areas.
    • Verify grid-column and grid-row spans don’t exceed defined tracks.
    • Check for implicit vs. explicit grid tracks if items are misaligned.

Conclusion

  • Flexbox shines in one-dimensional, content-driven layouts where flexibility and simplicity are key.
  • CSS Grid excels in two-dimensional, layout-driven designs requiring precise control over rows and columns.
  • Combine both for powerful, responsive layouts that balance structure and adaptability.

Experiment with the examples above by tweaking properties like justify-content, align-items, grid-template, or gap. Use browser dev tools to visualize layouts and test responsiveness. As you gain experience, you’ll intuitively know when to reach for Flexbox, Grid, or both to achieve your design goals.

Top comments (2)

Collapse
 
dotallio profile image
Dotallio

This is exactly the kind of side-by-side examples I needed, especially seeing how you combine both in real projects. Curious, what's your favorite Grid/Flexbox combo setup for tricky layouts?

Collapse
 
torquecloud profile image
Akash

For tricky layouts, we use grid for the root layout while usage of flexbox or grid for nested layouts depends on the requirement. So it is difficult to define a favorite combo for such layouts.

There are many layouts which can be achieved with both grid and flexbox and choosing one over other really depends on the complexity of one solution over other.

Some comments may only be visible to logged-in visitors. Sign in to view all comments.