Container Size Queries in the Wild

Container queries are still working their way into production workflows, and browser support is solid enough to start experimenting even if it’s not yet universal. But even with support limitations in mind, there are patterns that are almost begging for container query units. Here are a few cases where container size queries would have been the right tool for the job.

Scaling Card Contents Without Knowing the Viewport

The classic card grid problem is keeping an aspect ratio while scaling the typography and spacing inside each card. When you size contents based on the viewport, you tie the component to its surrounding context. If the card grid gets used in another place with different breakpoints, the component can break.

One workaround is to listen for resize events, measure each card’s width, and then write an inline font size per card. Everything inside then gets styled in em units. It works, but it’s fragile and verbose for something a pure CSS solution should be able to handle.

Container query units change that. The cqw unit is equal to 1% of a container’s width, while cqi targets inline width and cqb targets block width. So, with a container that’s 500px wide, 50cqw computes to 250px.

If a card component is set as a container:

.card { 
  container: card / size;
}

…then an inner wrapper can scale its padding using the same unit:

.card__inner { 
  padding: 10cqw; 
} 

The spacing between the card edge and contents then scales consistently no matter where the card appears. No media queries needed at the viewport level. The same logic can also drive the font size—setting a nested element’s font size in cqw and padding in em gives you spacing that tracks the card’s own width:

.card__inner { 
  font-size: 5cqw; 
  padding: 2em;
} 

The trick is that the padding is relative to the font size set on the same element, which itself is relative to the nearest container. Moving that font size deeper—for example applying it to a child that isn’t directly in the container—will change the reference. That means any inner wrapper needs to be set up as its own container to capture the right scale.

Fluid Layout Swaps for a Single Component

When a card layout needs to rotate between landscape and portrait at different viewport ranges, media queries lock the component to those exact viewport sizes. That works fine until the component moves into a sidebar, a modal, or another context where those breakpoints don’t match. You end up tuning breakpoints per placement, which duplicates the work.

A container query handles the switch based on the card itself:

.info-card {
  container-type: inline-size;
  container-name: info-card;
}

@container info-card (max-width: 500px) {
  .info-card__inner {
    flex-direction: column;
  }
}

The same layout rule then behaves correctly in any spot on the page, regardless of the viewport. The only real caveat is for systems that consume props for visual state—a portrait layout might require an alternate style on a child component, but you can’t alter JavaScript props with CSS. A designed container query system has to account for this up front.

Icon Stroke Weight That Snaps to Container Width

For a simple icon-and-heading lockup, scaling the icon alongside fluid type works naturally. The tricky part is the SVG stroke: scaling linearly with the heading font size is easy, but making the stroke snap to a particular width within certain ranges requires something more deliberate. Outside of viewport-level media queries, there was no clean way to do that.

Using a container query here lets the stroke width respond to the container’s own size and only change when needed:

.icon {
  container: icon / size; 
  width: 1em; 
  height: 1em; 
}

.icon svg {
  width: 100%; 
  height: 100%; 
  fill: none; 
  stroke: #ccc; 
  stroke-width: 0.8; 
}

@container icon (max-width: 70px) {
  .icon svg {
    stroke-width: 1.5; 
  }
}
@container icon (max-width: 35px) {
  .icon svg {
    stroke-width: 3;
  }
}

Rather than applying a class per icon instance with a fixed stroke width, the icon’s stroke adjusts based on the width of its own parent container. The same icon works in multiple contexts without extra JavaScript or viewport-dependent classes.

Beyond Width and Height Queries

The common examples all focus on width, height, min/max sizes and inline or block dimensions. But the size-related query options also include other conditions that previously belonged to media queries alone.

The orientation feature is basically the same concept as media queries—a container query checking for landscape or portrait:

@media screen (orientation: landscape) { 
  .info-card__inner {
    /* Style away! */
  }
} 

@container info-card (orientation: landscape) { 
  .info-card__inner {
    /* Style away! */
  }
} 

The other is aspect-ratio, which checks the shared value of the container’s dimensions, not just a single side:

@container info-card (aspect-ratio: 3/2) { 
  .info-card__inner {
    /* Style away! */
  }
} 

It’s not immediately obvious where these fit into daily layout work yet, but they fill gaps you only notice once you start reaching past the basic size query patterns.