CSS Container Queries & Modern Layouts
While traditional media queries make styling decisions based on the width of the entire browser viewport, CSS Container Queries (@container) allow elements to query the dimensions and styles of their immediate parent container. This enables true modular, component-driven responsive design.
1. The Limitation of Viewport Media Queriesβ
With standard viewport @media queries, a UI component (like a card) responds strictly to screen width, regardless of where it is placed on the page:
βββββββββββββββββββββββββββββββββββββββββββββββββββ ββββββββββββ
β VIEWPORT β
β β
β βββββββββββββββββββββββββββββ ββββββββββββββββββββββββββ β
β β Main Content Column (70%) β β Sidebar Column (30%) β β
β β β β β β
β β βββββββββββββββββββββββββ β β ββββββββββββββββββββββ β β
β β β Card Component β β β β Card Component β β β
β β β (Wants Wide Layout) β β β β (Wants Stacked) β β β
β β βββββββββββββββββββββββββ β β ββββββββββββββββββββββ β β
β βββββββββββββββββββββββββββββ ββββββββββββββββββββββββββ β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Both cards above see the same viewport width, forcing developers to create fragile context-dependent modifier classes (e.g., .card--sidebar). Container queries resolve this completely.
2. Defining a Containment Context (container-type)β
To query a parent element's size, you must first register it as a container using container-type and optionally assign a container-name.
/* Step 1: Register the Container */
.card-wrapper {
/* Establishes inline-size (width) containment */
container-type: inline-size;
container-name: card-host;
}
Container Type Optionsβ
| Value | Description |
|---|---|
inline-size (Most Common) | Queries the inline dimension (width) of the container. Avoids infinite height layout loops. |
size | Queries both inline (width) and block (height) dimensions. Requires explicit container height. |
normal | Removes containment tracking from the element. |
3. Querying the Container (@container)β
Once a container context is established, child elements can target it using @container queries:
/* Base Mobile/Narrow Component Styles */
.card {
display: flex;
flex-direction: column;
gap: 0.75rem;
}
/* Step 2: Component responds when wrapper width reaches 400px */
@container (min-width: 400px) {
.card {
flex-direction: row;
align-items: center;
}
.card-image {
width: 150px;
height: 100%;
}
}
4. Container Query Length Unitsβ
CSS Container Queries introduce dynamic length units relative to the container's dimensions:
| Unit | Description | Relative Measurement |
|---|---|---|
cqw | Container Query Width | 1% of container's width |
cqh | Container Query Height | 1% of container's height |
cqi | Container Query Inline | 1% of container's inline size |
cqb | Container Query Block | 1% of container's block size |
cqmin | Container Query Minimum | Smaller value of cqi or cqb |
cqmax | Container Query Maximum | Larger value of cqi or cqb |
.card-title {
/* Font size scales smoothly based on container width, not viewport */
font-size: clamp(1rem, 5cqw, 1.75rem);
}
Interactive Playground: Modular Responsive Cardβ
Resize or view the card wrapper to see the component dynamically adapt its layout based on container width:
Summary Reference Tableβ
| Feature / Syntax | Example | Purpose |
|---|---|---|
container-type | container-type: inline-size; | Registers element as a queryable container |
container-name | container-name: sidebar; | Names container for targeting specific parents |
container shorthand | container: sidebar / inline-size; | Combines container name and type |
@container Query | @container (min-width: 400px) { ... } | Applies conditional styles based on container size |
| Container Units | font-size: 4cqw; | Sizes elements relative to container dimensions |