CSS Container Queries
Overview
Container Queries allow components to adapt their styling based on the size of their containing element rather than the viewport. This enables truly reusable, context-aware components that respond to their available space.
When to Use
- Building reusable components that work in different layout contexts
- Card components that adapt between sidebar and main content
- Design systems where components must be layout-agnostic
- Replacing JavaScript-based resize observers for responsive components
Core Patterns
Basic Container Query
/* Define a containment context */
.card-container {
container-type: inline-size;
container-name: card;
}
/* Query the container's size */
@container card (min-width: 400px) {
.card {
display: grid;
grid-template-columns: 200px 1fr;
gap: 1rem;
}
}
@container card (max-width: 399px) {
.card {
display: flex;
flex-direction: column;
}
}
Container Query Units
/* cqw = 1% of container width */
/* cqh = 1% of container height */
/* cqi = 1% of container inline size */
/* cqb = 1% of container block size */
/* cqmin = min(cqi, cqb) */
/* cqmax = max(cqi, cqb) */
.card-title {
font-size: clamp(1rem, 3cqi, 2rem);
}
.card-image {
height: 40cqb;
}
Style Queries (Experimental)
/* Query custom property values */
@container style(--theme: dark) {
.card {
background: #1a1a2e;
color: #eee;
}
}
@container style(--variant: compact) {
.card {
padding: 0.5rem;
}
}
Nested Containers
.sidebar {
container-type: inline-size;
container-name: sidebar;
}
.sidebar .widget {
container-type: inline-size;
container-name: widget;
}
@container sidebar (max-width: 300px) {
.sidebar-nav { flex-direction: column; }
}
@container widget (min-width: 200px) {
.widget-content { display: grid; grid-template-columns: 1fr 1fr; }
}
Tailwind CSS v4 Integration
<!-- Tailwind v4 has native container query support -->
<div class="@container">
<div class="flex flex-col @sm:flex-row @md:grid @md:grid-cols-3">
<p class="text-sm @lg:text-base">Responsive to container</p>
</div>
</div>
Guidelines
- Use
container-type: inline-sizefor most use cases (width-based queries) - Name your containers with
container-namefor clarity in nested contexts - Use container query units (
cqi,cqw) for fluid typography and spacing - Combine with
@media— use container queries for components, media queries for layout - Progressive enhancement — provide reasonable defaults for non-supporting browsers
Anti-Patterns
- ❌ Using
container-type: sizewhen only inline-size is needed (causes unnecessary layout containment) - ❌ Nesting containers without naming them (ambiguous query targets)
- ❌ Replacing all media queries with container queries (they serve different purposes)
- ❌ Forgetting that
container-typecreates a new stacking context