On this page
A product teaser can appear in a wide search result, a narrow sidebar, or a two-column recommendations panel. A viewport breakpoint cannot distinguish those placements when they share the same page. Container queries let the component respond to its actual available space instead of guessing from the browser width.
Define the component boundary first
Start with a component that has two useful arrangements: stacked content when narrow and an image beside text when wider. Use the CSS Grid Generator to sketch the wide arrangement, then copy only the track definitions and gap you need. The tool helps establish the layout; the container query decides when that layout applies.
The important distinction is available space, not device category. A teaser inside a sidebar should stay stacked even on a large monitor. Give the wrapper responsibility for measurement and the inner component responsibility for presentation. This separation also makes the same markup useful in different templates without modifier classes for every placement.
Write down the minimum space needed by each piece. An image might need ten rem, text might need sixteen rem, and their gap might need one rem. That suggests an initial threshold near twenty-seven rem, which you should validate with actual content rather than treat as a universal breakpoint.
Establish containment without collapsing the layout
Apply container-type: inline-size to the wrapper whose inline dimension the parent layout already determines. In ordinary horizontal writing, that means its width. Avoid full size containment unless you deliberately manage both dimensions: removing content contributions from block sizing can produce surprising heights.
.teaser-slot {
container-type: inline-size;
container-name: teaser;
}
.teaser {
display: grid;
gap: 1rem;
}
.teaser img {
display: block;
inline-size: 100%;
aspect-ratio: 4 / 3;
object-fit: cover;
}
@container teaser (min-width: 28rem) {
.teaser {
grid-template-columns: minmax(0, 10rem) minmax(0, 1fr);
align-items: start;
}
}The query styles descendants of the matching container, not that container itself based on its own size. This wrapper pattern avoids a circular sizing dependency. The wrapper can still have ordinary declarations, but put the changing grid on its child.
Read MDN’s container query guide when choosing containment modes. In a flex parent, check whether the wrapper also needs min-inline-size: 0 so long content does not force it wider than intended.
Name containers when components are nested
An unnamed size query uses an eligible ancestor container. That is convenient in a small demonstration but can become ambiguous when a teaser contains another reusable component that also establishes containment. Named containers make the intended measurement boundary explicit.
Use names that describe a layout responsibility, such as teaser or results, rather than a screen size. A name like desktop becomes misleading when the same wide component appears inside a tablet landscape panel. Container names are identifiers, not a promise about hardware.
Keep thresholds close to the component stylesheet. A site-wide media query can still manage the page shell, while the teaser responds locally. These two mechanisms solve different problems and can coexist. For a broader distinction between layout systems, see the existing Grid and Flexbox guide.
Test nesting deliberately. Place a teaser inside a contained results panel, then make both narrow and wide independently. If the teaser switches at the panel’s threshold rather than its own wrapper’s width, inspect which named ancestor the query actually finds.
Use container units with sensible bounds
Container query units can express sizes relative to an eligible query container. For example, cqi measures a percentage of its inline size. They can be useful for local spacing, but a raw percentage can become too small in a narrow slot or excessive in a large one.
Prefer bounded values such as padding: clamp(1rem, 3cqi, 2rem) on a descendant. Here the padding grows with the query container while staying between explicit limits. Remember that, without an eligible container, these units use the corresponding small viewport dimension rather than silently becoming zero.
Do not make every measurement fluid. Fixed gaps and a single structural switch are often easier to maintain than a component where padding, image width, borders, and spacing all change continuously. Add fluid behavior only when it solves a visible problem.
MDN’s length reference explains the unit families. When reviewing the implementation, resize the parent independently of the viewport. A draggable split panel is a particularly useful fixture because it exposes accidental dependencies on global breakpoints.
Ship a useful baseline and inspect edge cases
The stacked layout in the example is the baseline fallback. Browsers without the query behavior still receive readable content and correctly sized images. You can add an explicit support check when an enhancement is complex, but do not hide essential content behind feature detection.
Follow web.dev’s container query overview for additional implementation context. Confirm support against your own browser policy rather than assuming every embedded webview matches the newest desktop release. A fallback is successful when the component remains useful, not when it reproduces every enhancement.
Check intrinsic sizing with an unbroken URL, a missing image, a translated heading, and a button with a longer label. Use overflow-wrap: anywhere on text that can legitimately contain long tokens. Do not apply clipping to the entire component simply to conceal the symptom.
Also inspect the threshold at one pixel below and above the switch. A horizontal arrangement that technically fits may still leave text with an unusably narrow measure. Raise the breakpoint or reduce the image track based on content, not on a memorized device width.
Document the measurement contract alongside other HTML and CSS guides: which element establishes containment, which name descendants query, and whether the parent must allocate width. That small note prevents future refactors from moving containment to an element whose size depends entirely on its children.
Key takeaways
- Measure the component’s parent space rather than infer it from the viewport.
- Put containment on a wrapper and layout changes on descendants.
- Name containers when reusable components can nest.
- Keep local fluid values bounded and preserve a readable stacked fallback.
- Test long content, nested containers, and both sides of every threshold.
Reach designers & developers at work
Put your product next to the tools people use every day. One sponsor per placement, no tracking pixels.
Become a sponsor