Web Development

CSS Modern Layout: Grid, Flexbox, and Container Queries

CSS Modern Layout: Grid, Flexbox, and Container Queries

Web Development March 12, 2026 · 6 min read · 1,284 words

CSS Modern Layout Techniques: Grid, Flexbox, and Container Queries in 2026

CSS layout has undergone a revolution. Gone are the days of float-based hacks and clearfix workarounds. In 2026, three layout systems form the foundation of modern CSS: CSS Grid for two-dimensional layouts, Flexbox for one-dimensional alignment, and Container Queries for truly component-responsive design. Together, they give developers unprecedented control over page structure.

According to the 2025 State of CSS survey, Grid is now used by 91% of developers, Flexbox by 98%, and Container Queries by 47% with rapidly growing adoption. This guide covers each technology in depth with practical examples you can use immediately.

CSS Flexbox: One-Dimensional Layout Mastery

When to Use Flexbox

Flexbox excels at distributing space along a single axis — either horizontal or vertical. Use it for:

  • Navigation bars and toolbars
  • Centering content vertically and horizontally
  • Card rows that need equal height
  • Form input groups
  • Any layout where items flow in one direction

Essential Flexbox Patterns

Pattern 1: The Holy Grail Navigation

A navigation bar with logo on the left, links in the center, and actions on the right:

/* Navigation with three sections */
.navbar {
  display: flex;
  align-items: center;
  padding: 1rem 2rem;
  gap: 1rem;
}

.navbar-logo {
  flex: 0 0 auto; /* Don't grow, don't shrink */
}

.navbar-links {
  display: flex;
  flex: 1 1 auto; /* Grow to fill space */
  justify-content: center;
  gap: 2rem;
}

.navbar-actions {
  flex: 0 0 auto;
  display: flex;
  gap: 0.5rem;
}

Pattern 2: Equal-Height Cards

Cards that always match the height of the tallest sibling, with the button pushed to the bottom:

.card-grid {
  display: flex;
  flex-wrap: wrap;
  gap: 1.5rem;
}

.card {
  display: flex;
  flex-direction: column;
  flex: 1 1 300px; /* Grow, shrink, minimum 300px */
  max-width: 400px;
  padding: 1.5rem;
  border: 1px solid #e2e8f0;
  border-radius: 8px;
}

.card-body {
  flex: 1; /* Pushes footer to bottom */
}

.card-footer {
  margin-top: auto; /* Sticks to bottom regardless of content height */
}

Pattern 3: Perfect Centering

The simplest way to center anything both vertically and horizontally:

.centered-container {
  display: flex;
  justify-content: center;
  align-items: center;
  min-height: 100vh;
}

/* Alternative: even simpler with place-content */
.centered-container {
  display: flex;
  place-content: center;
  min-height: 100vh;
}

Flexbox Gap: The Modern Spacing Solution

The gap property (supported in Flexbox since 2021 with now 99% browser support) replaces the old margin-based spacing hacks:

/* Old approach: margin with negative margin wrapper */
.old-list > * {
  margin: 0 8px 8px 0;
}
.old-list {
  margin-right: -8px; /* Compensate */
}

/* Modern approach: gap */
.modern-list {
  display: flex;
  flex-wrap: wrap;
  gap: 8px; /* Clean, no hacks needed */
}

CSS Grid: Two-Dimensional Layout Power

When to Use Grid

CSS Grid is designed for two-dimensional layouts where you control both rows and columns simultaneously. Use it for:

  • Page-level layouts (header, sidebar, main, footer)
  • Image galleries and masonry layouts
  • Dashboard layouts with varying-size widgets
  • Any layout requiring precise row and column alignment

Essential Grid Patterns

Pattern 1: Responsive Grid Without Media Queries

The most powerful Grid technique is auto-fit with minmax(), which creates a responsive grid that adjusts column count automatically:

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

/* Result:
   - 4 columns on large screens
   - 3 columns on medium screens
   - 2 columns on tablets
   - 1 column on mobile
   ALL without a single media query */

Pattern 2: The Classic Page Layout

A full page layout with named grid areas makes the template readable and maintainable:

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

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

/* Responsive: stack on mobile */
@media (max-width: 768px) {
  .page-layout {
    grid-template-areas:
      "header"
      "main"
      "sidebar"
      "footer";
    grid-template-columns: 1fr;
  }
}

Pattern 3: Dashboard with Spanning Widgets

Grid's spanning capabilities make it perfect for dashboards where widgets vary in size:

.dashboard {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  grid-auto-rows: minmax(200px, auto);
  gap: 1rem;
}

.widget-large {
  grid-column: span 2;
  grid-row: span 2;
}

.widget-wide {
  grid-column: span 2;
}

.widget-tall {
  grid-row: span 2;
}

/* All other widgets auto-place into remaining cells */

Subgrid: Aligning Nested Content

Subgrid, now supported in all major browsers (Chrome 117+, Firefox 71+, Safari 16+), lets nested grids inherit track sizing from their parent. This solves the common problem of aligning card titles, bodies, and footers across a row:

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

.card {
  display: grid;
  grid-template-rows: subgrid; /* Inherit row tracks from parent */
  grid-row: span 3; /* Card occupies 3 rows: title, body, footer */
}

/* Now all card titles align, all bodies align, all footers align
   regardless of content length in each card */

Container Queries: Component-Level Responsiveness

The Problem with Media Queries

Media queries respond to the viewport width. But components live inside containers that may be any size — a sidebar, a modal, a grid column. A card component that looks great in a 3-column layout breaks when placed in a narrow sidebar, even though the viewport hasn't changed.

Container Queries solve this by letting components respond to their container's size instead of the viewport.

Setting Up Container Queries

First, establish a containment context on the parent element:

/* Define the container */
.card-wrapper {
  container-type: inline-size;
  container-name: card; /* Optional: name it for clarity */
}

/* Shorthand */
.card-wrapper {
  container: card / inline-size;
}

/* Now the card responds to its container's width, not the viewport */
.card {
  display: grid;
  grid-template-columns: 1fr;
  gap: 1rem;
}

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

@container card (min-width: 600px) {
  .card {
    grid-template-columns: 200px 1fr;
    gap: 1.5rem;
  }

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

Practical Container Query Example: Product Card

A product card that adapts whether it is in a wide main content area or a narrow sidebar:

/* Containment context */
.product-container {
  container: product / inline-size;
}

/* Default: narrow layout (sidebar, mobile) */
.product-card {
  display: flex;
  flex-direction: column;
  padding: 1rem;
  border-radius: 8px;
  border: 1px solid #e2e8f0;
}

.product-card img {
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  border-radius: 4px;
}

.product-info {
  padding-top: 0.75rem;
}

.product-price {
  font-size: 1.25rem;
  font-weight: 700;
}

/* Medium: horizontal card */
@container product (min-width: 450px) {
  .product-card {
    flex-direction: row;
    gap: 1.5rem;
  }

  .product-card img {
    width: 180px;
    flex-shrink: 0;
  }
}

/* Large: full-featured display */
@container product (min-width: 700px) {
  .product-card {
    padding: 1.5rem;
  }

  .product-card img {
    width: 250px;
  }

  .product-price {
    font-size: 1.75rem;
  }

  .product-actions {
    display: flex;
    gap: 0.5rem;
  }
}

Container Query Units

Container Queries also introduce new units that are relative to the container's size:

  • cqw — 1% of the container's width
  • cqh — 1% of the container's height
  • cqi — 1% of the container's inline size
  • cqb — 1% of the container's block size
  • cqmin / cqmax — the smaller / larger of cqi and cqb
.responsive-heading {
  /* Font size scales with container width */
  font-size: clamp(1rem, 4cqi, 2.5rem);
}

.responsive-padding {
  /* Padding scales with container */
  padding: clamp(0.5rem, 3cqi, 2rem);
}

Combining All Three: A Real-World Layout

The true power emerges when you combine Grid, Flexbox, and Container Queries together. Here is a complete dashboard layout:

/* Grid for the overall page layout */
.dashboard {
  display: grid;
  grid-template-columns: 250px 1fr;
  grid-template-rows: 64px 1fr;
  grid-template-areas:
    "nav header"
    "nav main";
  min-height: 100vh;
}

/* Flexbox for the header toolbar */
.dashboard-header {
  grid-area: header;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 2rem;
}

/* Grid for the widget area */
.dashboard-main {
  grid-area: main;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: 1.5rem;
  padding: 1.5rem;
}

/* Container queries for individual widgets */
.widget-wrapper {
  container: widget / inline-size;
}

.widget {
  padding: 1rem;
  border-radius: 8px;
  background: white;
}

@container widget (min-width: 500px) {
  .widget-chart {
    aspect-ratio: 16 / 9;
  }
  .widget-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
  }
}

/* Flexbox for the sidebar navigation */
.dashboard-nav {
  grid-area: nav;
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
  padding: 1rem;
  background: #1a1a2e;
}

Decision Guide: Grid vs Flexbox vs Container Queries

Use this decision framework to choose the right tool:

  • Layout in one direction? → Flexbox
  • Layout in two directions (rows and columns)? → Grid
  • Component should adapt to its container, not the viewport? → Container Queries
  • Auto-flowing content of unknown quantity? → Flexbox (wrap) or Grid (auto-fit)
  • Precise placement of items in named areas? → Grid (template-areas)
  • Aligning nested content across siblings? → Grid (subgrid)

In practice, most layouts use a combination. Grid structures the page, Flexbox aligns items within sections, and Container Queries make components portable and reusable across different contexts. Master all three, and you can build any layout without a single line of JavaScript.

Browser Support in 2026

All three technologies have excellent browser support:

  • Flexbox: 99.5% global support — fully safe for production
  • CSS Grid: 98% global support — fully safe for production
  • Subgrid: 93% global support (Chrome 117+, Firefox 71+, Safari 16+)
  • Container Queries: 92% global support (Chrome 105+, Firefox 110+, Safari 16+)
  • Container Query Units: 91% global support

For the small percentage of older browsers that don't support Container Queries, the default (non-queried) styles serve as a natural fallback, so your layouts degrade gracefully.

css grid flexbox container queries modern css layout css grid tutorial container queries guide 2026

About the Author

S
Sam Parker
Lead Editor, ViralVidVault
Sam Parker is the lead editor at ViralVidVault, specializing in technology, entertainment, gaming, and digital culture. With extensive experience in content curation and editorial analysis, Sam leads our coverage of trending topics across multiple regions and categories.

Related Articles