Quick, practical intro to CSS container queries - a way to make components adapt to their own container size (context), not the viewport. This is a big shift from media queries!
<!-- Minimal, attribute-free structure -->
<card>
<h2>Title</h2>
<p>Content…</p>
</card>/* 1) Opt a component into querying its own inline size */
card {
container-type: inline-size; /* establish a queryable container */
display: grid;
gap: 0.75rem;
padding: 1rem;
border: 1px solid CanvasText;
border-radius: 0.5rem;
}
/* 2) Component becomes responsive to its container, not the viewport */
@container (width > 40rem) {
card {
grid-template-columns: 1fr 2fr;
align-items: start;
}
card > h2 { font-size: 1.35rem; }
}
/* 3) Progressive enhancement (legacy fallback keeps working) */
@supports not (container-type: inline-size) {
/* Optional: a conservative layout that still looks fine */
card { display: block; }
}- Self‑aware UI: Reusable elements don’t need page‑level breakpoints. Drop
<card>anywhere and it adapts. - Isolation: Layout logic lives in the component’s CSS; no JS, no global classes/IDs.
- Predictable fallbacks: With
@supportsyou keep old browsers functional without branching HTML or JS.
/* Name + scope multiple query axes if needed */
dashboard { container: dashboard inline-size; } /* (name is optional) */
@container dashboard (width > 60rem) { /* … */ }
/* Style based on container style queries (lightweight variants) */
@container style(--variant: "compact") {
card { padding: 0.5rem; }
}
/* Set the custom property on the parent container to flip modes */
cards[compact] { --variant: "compact"; }
/* Nested parts coordinate via :has() without IDs/classes */
section:has(card + card + card) { /* 3+ cards */ gap: 1.25rem; }- Add
container-type: inline-size;to any component wrapper you want responsive. - Replace page‑wide
@media (min-width: …)rules with@container (width > …). - Keep a small
@supports not (container-type: …)block for legacy. - Use custom properties for lightweight “modes” (e.g.,
--variant) set on the container.
