Replacing Media Queries with CSS Container Queries

For more than a decade, responsive web design has been synonymous with viewport-based media queries. Developers wrote media queries targeting screen dimensions (such as @media (min-width: 768px)) to adjust layouts for mobile, tablet, and desktop screens.

While media queries revolutionized web design, they suffer from a fundamental architectural limitation: they assume that a component's visual style should change based on the size of the browser window. In modern component-driven architectures (like React, Vue, or Web Components), this assumption breaks down. A component should adjust its styling based on the size of its parent container, not the viewport.

CSS Container Queries solve this issue by introducing container-based layout rules. Instead of query parameters defined by the viewport, a component checks the dimensions of its closest designated ancestor element. This approach allows developers to build truly encapsulated, reusable components that adapt fluidly regardless of where they are placed in a layout.

The Failure of Viewport-Centric Design Systems

Consider a standard card component containing an image, a heading, and body text. In a viewport-centric design system, if that card is placed in a narrow sidebar, it should display a vertical, stacked layout. If the exact same card is placed in a wide main content area, it should display a horizontal, side-by-side layout.

With media queries, achieving this is difficult. Because both layouts exist on the same screen size (desktop), a simple media query cannot distinguish between the sidebar location and the main content location. Developers had to write complex override classes (e.g., .card--sidebar vs .card--hero), which creates brittle CSS structures and breaks encapsulation.

By moving to container queries, the card component becomes self-aware. It handles its own responsiveness based on the space allocated to it, removing the need for contextual wrapper overrides.

If the sidebar is 300px wide, the card styles itself as a small block. If the main area is 800px wide, it styles itself as a wide hero banner.

Declaring Containers and Containment Types

To use container queries, you must first define a parent element as a container. This is done by applying the container-type property. There are two primary types of containment:

  • inline-size: This applies containment to the inline axis (usually width in horizontal writing modes). This is the most common container type, as layouts typically flow vertically and adapt horizontally.
  • size: This applies containment to both the inline and block axes (width and height). The container's size must be explicitly defined, as the browser will not calculate its size based on its contents.

At Bramsley Digital Studio, we can also use the container-name property to target specific containers, or use the shortcut container property to declare both type and name together (e.g., container: sidebar / inline-size).

Writing a Container Query

Once a parent container is established, we target descendant elements using the @container rule. Below is a complete CSS and HTML example showing how a card component dynamically adjusts its layout based on container size:

/* HTML Structure
<div class="card-container">
  <div class="responsive-card">
    <img src="thumb.jpg" alt="Preview" class="card-image" />
    <div class="card-content">
      <h3>Optimizing CSS Architectures</h3>
      <p>Learn how container queries encapsulate responsive styling.</p>
    </div>
  </div>
</div>
*/

/ Define the wrapper as the layout container /
.card-container {
  container-type: inline-size;
  container-name: card-wrapper;
  width: 100%;
}

/ Default mobile-first layout (stacked) /
.responsive-card {
  display: flex;
  flex-direction: column;
  gap: 1rem;
  padding: 1rem;
  background: var(--bg-card);
  border-radius: 8px;
}

/ Adjust layout when container width exceeds 500px /
@container card-wrapper (min-width: 500px) {
  .responsive-card {
    flex-direction: row;
    align-items: center;
  }
  
  .card-image {
    width: 200px;
    height: auto;
    border-radius: 4px;
  }
  
  .responsive-card h3 {
    font-size: 1.5rem;
  }
}

Container Query Units

In addition to media rules, the specification introduces Container Query Length Units. These function similarly to viewport units (vw, vh) but are relative to the dimensions of the active query container instead of the browser viewport:

  • 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: The smaller value of cqi or cqb.
  • cqmax: The larger value of cqi or cqb.

These units allow for extremely fluid typography and spacing. For instance, setting a heading's font size to font-size: clamp(1rem, 4cqi, 2.5rem) ensures that the text scales harmoniously as the containing element expands or contracts.

Building Enterprise Design Systems with Bramsley

Adopting container queries requires a fundamental shift in how design systems are planned and executed. To help teams transition, Bramsley Digital Studio designs and builds modular, edge-delivered component libraries with fully encapsulated container query architectures using modern CSS patterns.

  • Zero Cumulative Layout Shift: By encapsulating styling logic directly within components, we minimize cumulative layout shifts and improve rendering performance.
  • Micro-Frontend Readiness: Our responsive UI modules are drop-in ready for edge dashboards, micro-frontends, and high-conversion e-commerce pages.
  • Edge-Scale Optimization: Layout queries execute instantly in the client browser, backed by fast, edge-cached static assets.

Bramsley Digital Studio

Enterprise Digital Architecture

We engineer digital infrastructure that drives measurable B2B growth. Experts in Legacy System Migration and High-Performance Frontends.

Architecture Specs & Case Studies

Scale Your Operations

  • Legacy System Migration
  • Scalable Infrastructure
  • High-Performance Frontends
  • Global Edge Deployment