CSS Container Queries arrived in all major browsers in 2023 and solve a longstanding limitation of responsive design: media queries respond to the viewport width, not the width of the element’s parent container. A card component placed in a three-column grid behaves differently than the same card in a single-column widget area, yet media queries cannot distinguish between the two contexts without JavaScript or duplicate CSS rulesets. Container queries let the card component itself decide its layout based on how much space its containing element provides, making truly reusable block components possible. WordPress block themes are the ideal context for container queries because blocks appear in varying column widths across templates — a card block in a columns block behaves differently from the same card in a full-width template. To use container queries, the parent element needs container-type: inline-size (or size) and an optional container-name for targeting. The @container rule then functions identically to @media but measures the named container rather than the viewport. Naming containers is optional but recommended when multiple nesting levels exist, to prevent an inner container query from accidentally matching a grandparent container. The cqi, cqb, cqw, and cqh units express sizes relative to the container dimensions, replacing vw/vh for container-aware sizing. The CSS grid guide explains the grid structure that surrounds container-query components — the grid defines column widths while container queries respond to them. The custom properties post shows how to store breakpoint values and component dimensions as tokens that container query thresholds and cq* units can reference for consistency. Polyfilling container queries for older browsers via container-query-polyfill is possible but adds JavaScript overhead — check your analytics before deciding whether progressive enhancement without a polyfill is acceptable.
Problem: Media queries in WordPress themes respond only to viewport width, making card and widget components unable to adapt their layout when placed in narrow columns versus wide full-width template areas on the same page.
Solution: Apply container-type: inline-size to wrapper elements and use @container rules inside block or theme stylesheets so each component adapts to its available space regardless of viewport size.
/* Mark the block wrapper as a container */
.wp-block-columns .wp-block-column,
.card-wrapper,
.widget-area {
container-type: inline-size;
container-name: card-container;
}
/* Card component — default: stacked (narrow context) */
.card {
display: grid;
grid-template-columns: 1fr;
gap: 1rem;
}
.card__image { aspect-ratio: 16 / 9; object-fit: cover; width: 100%; }
.card__body { padding: 1rem; }
.card__title { font-size: 1.1rem; }
/* When the container is at least 480px wide: side-by-side layout */
@container card-container (min-width: 480px) {
.card {
grid-template-columns: 200px 1fr;
}
.card__image {
aspect-ratio: 1;
}
.card__title {
font-size: 1.25rem;
}
}
/* Fluid font size using cqi units */
@container card-container (min-width: 300px) {
.card__excerpt {
font-size: clamp(0.875rem, 2cqi, 1rem);
}
}
NOTE: Container queries require container-type on a parent element, not on the component itself — adding it directly to .card would make the card query its own size before layout, which browsers treat as zero and prevent the query from ever matching.