{"id":"xwk4zxdnb9etls8","title":"Container Queries: Responsive Components Without Breakpoint Guessing","slug":"container-queries-responsive-components","summary":"Viewport media queries lie inside grids and sidebars. I size components from their parent box with container queries and stay sane.","imageUrl":"https://briancrabtree.me/images/journal-container-queries-responsive-components.webp","category":"CSS","date":"2026-03-09T18:00:00.000Z","featured":false,"likes":35,"author":"Brian Crabtree","content":"<h2>Why viewport breakpoints break</h2>\n\n<p>A card that looks perfect at 768px viewport may sit in a 280px sidebar because layout changed. Media queries cannot see parent width. Container queries let the component respond to the space it actually has.</p>\n\n<p>I still use page-level breakpoints for global nav and page grid. Component internals use @container.</p>\n\n<p>Container query length units cqi and cqw help typography inside cards when inline-size is established. I test in Safari stable, not only Chrome canary.</p>\n\n<pre><code>.card-grid { container-type: inline-size; }\n\n@container (min-width: 28rem) {\n  .card { display: grid; grid-template-columns: 1fr 2fr; }\n}</code></pre>\n\n<p><figure>\n  <img src=\"/images/journal-inline-container-queries.webp\" alt=\"Diagram of container queries resizing card layout based on parent width not viewport\" width=\"1200\" height=\"675\" loading=\"lazy\" />\n  <figcaption>Components should respond to their container — not the whole viewport.</figcaption>\n</figure></p>\n\n<h2>container-type and naming</h2>\n\n<p>Parent gets container-type: inline-size or size. Child rules use @container (min-width: 24rem). I name containers with container-name when multiple nested contexts need disambiguation.</p>\n\n<p>Establishing containers on every div is noise. I pick card, sidebar, and article body wrappers deliberately.</p>\n\n<p>Grid with minmax and auto-fit pairs well with containers: outer grid sets page columns, inner container handles card innards.</p>\n\n<h2>Patterns I reuse</h2>\n\n<p>Card stacks switch from single column to row when the card is wide enough, not when the phone rotates. Data tables scroll inside narrow containers instead of forcing page-level horizontal scroll. Typography scales down inside tight aside columns without shrinking the main article.</p>\n\n<p>Combine with clamp() for fluid type inside containers. The query handles layout mode; clamp handles micro scaling.</p>\n\n<p>Print stylesheets still matter for invoices and spec sheets. Containers do not replace @media print page rules.</p>\n\n<h2>Fallbacks for older browsers</h2>\n\n<p>Evergreen public sites can use containers today. Enterprise lag gets a min-width media fallback that approximates the sidebar case, then @supports container queries override. Test in Safari and Firefox, not only Chrome.</p>\n\n<p>Storybook viewports should include narrow container frame, not only iPhone full screen, or components ship broken in sidebars.</p>\n\n<p>When I audit css stacks, Fallbacks for older browsers is where hours disappear if nobody owns the outcome. I write before-and-after notes, attach PSI or waterfall screenshots, and leave the team a three-item follow-up list. Reproducible wins beat toolchain debates in sprint review. If this section matches your bottleneck, send the URL and whether LCP, INP, CLS, or crawl coverage is the pain point.</p>\n\n<h2>React and CSS modules</h2>\n\n<p>Container rules live in the same stylesheet as the component. No prop drilling breakpoint constants from ResizeObserver unless I need JS measurements for canvas charts. CSS does the layout; JS does the data.</p>\n\n<p>Do not read container width in useEffect to set state every frame. That is layout thrash with extra steps.</p>\n\n<p>When container queries unsupported, single column fallback should still be usable, not broken half-width layout.</p>\n\n<h2>DevTools and debugging</h2>\n\n<p>Chrome shows container overlays when enabled. When styles fail, I verify an ancestor actually established a containment context. Anonymous size containment without inline-size is a common miss.</p>\n\n<p>Performance of container queries is good on modern browsers; still avoid querying hundreds of nested containers on scroll.</p>\n\n<p>When I audit css stacks, DevTools and debugging is where hours disappear if nobody owns the outcome. I write before-and-after notes, attach PSI or waterfall screenshots, and leave the team a three-item follow-up list. Reproducible wins beat toolchain debates in sprint review. If this section matches your bottleneck, send the URL and whether LCP, INP, CLS, or crawl coverage is the pain point.</p>\n\n<h2>Adoption advice</h2>\n\n<p>Refactor one card component used in grid and sidebar. Ship, measure support tickets about layout, expand. Container queries reduce bespoke breakpoint props in design systems. That is real velocity.</p>\n\n<p>Design handoff should mark container boundary on Figma frame, not only device breakpoint artboards.</p>\n\n<p>When I audit css stacks, Adoption advice is where hours disappear if nobody owns the outcome. I write before-and-after notes, attach PSI or waterfall screenshots, and leave the team a three-item follow-up list. Reproducible wins beat toolchain debates in sprint review. If this section matches your bottleneck, send the URL and whether LCP, INP, CLS, or crawl coverage is the pain point. For a related angle I keep coming back to, see <a href=\"/journal/mobile-first-css-that-scales/\">Mobile-First CSS That Scales Up Without Rewriting</a>.</p>","tags":["container-queries","css","layout"],"views":104}