|$ curl https://forge-ai.dev/api/markdown?path=docs/css/container-queries
$cat docs/css-container-queries.md
updated Yesterday·12 min read·published

CSS Container Queries

CSSContainer QueriesResponsiveAdvanced
Introduction

Container queries allow you to style elements based on the size of their parent container rather than the viewport. This is a paradigm shift from media queries — instead of asking "how wide is the screen?", you ask "how wide is my container?".

This enables truly reusable, context-aware components that adapt to wherever they are placed in a layout. A card component can rearrange itself whether it sits in a narrow sidebar or a wide main content area, without any viewport-based breakpoints.

container-query-basics.css
CSS
1.card-container {
2 container-type: inline-size;
3 container-name: card;
4}
5
6@container card (min-width: 400px) {
7 .card {
8 display: grid;
9 grid-template-columns: 1fr 2fr;
10 gap: 16px;
11 }
12}
13
14@container card (max-width: 399px) {
15 .card {
16 display: flex;
17 flex-direction: column;
18 }
19}
preview
container-type

The container-typeproperty establishes an element as a query container. It tells the browser to track the container's size so that child elements can query it.

container-type.css
CSS
1.element {
2 container-type: normal; /* default — no size containment */
3 container-type: inline-size; /* tracks inline-axis size (width) */
4 container-type: size; /* tracks both inline and block axis */
5}

inline-size is the most common value. It applies containment only on the inline axis, allowing the element to still grow vertically based on its content. size applies containment to both axes, which may cause content to overflow if not managed carefully.

warning

Elements with container-type set to inline-size or size create a new stacking context and act as containment roots. This affects how child elements with position: absolute or fixed behave.
container-name

The container-name property gives your container a name so that @container rules can target it specifically. This is essential when you have nested containers and need to query a particular ancestor.

container-name.css
CSS
1.sidebar-panel {
2 container-type: inline-size;
3 container-name: sidebar;
4}
5
6.main-content {
7 container-type: inline-size;
8 container-name: content;
9}
10
11/* Query the sidebar container specifically */
12@container sidebar (min-width: 300px) {
13 .widget { font-size: 1rem; }
14}
15
16/* Query the content container */
17@container content (min-width: 600px) {
18 .widget { font-size: 1.25rem; }
19}

You can also assign multiple names to a single container using a space-separated list:

container-multi-name.css
CSS
1.panel {
2 container-type: inline-size;
3 container-name: panel widget-area;
4}

The container shorthand combines both properties:

container-shorthand.css
CSS
1.sidebar {
2 container: sidebar / inline-size;
3}
4
5/* Equivalent to: */
6.sidebar {
7 container-type: inline-size;
8 container-name: sidebar;
9}
The @container Rule

The @container at-rule works similarly to @media, but queries the nearest container with container-type applied — or a named container if specified.

at-container.css
CSS
1/* Query the nearest container */
2@container (min-width: 400px) {
3 .child { color: #00FF41; }
4}
5
6/* Query a named container */
7@container card (min-width: 300px) {
8 .title { font-size: 1.5rem; }
9}
10
11/* Query container style (future Capability Query) */
12@container card (style(--theme: dark)) {
13 .body { background: #0D0D0D; }
14}

Container queries support the same comparison operators as media queries: min-width, max-width, and range syntax:

container-range.css
CSS
1/* Range syntax */
2@container (300px <= inline-size < 600px) {
3 .card { grid-template-columns: 1fr; }
4}
5
6/* Equivalent to: */
7@container (min-width: 300px) and (max-width: 599px) {
8 .card { grid-template-columns: 1fr; }
9}
Container Query Length Units

Container queries introduce six new length units that represent percentages of the container's dimensions. These work similarly to viewport units (vw, vh) but are relative to the nearest container rather than the viewport.

UnitRelative ToDescription
cqwContainer Width1% of the container's inline size
cqhContainer Height1% of the container's block size
cqiContainer Inline-Size1% of the container's inline size (text-direction aware)
cqbContainer Block-Size1% of the container's block size (text-direction aware)
cqminContainer MinThe smaller of cqi and cqb
cqmaxContainer MaxThe larger of cqi and cqb
cq-units.css
CSS
1.card {
2 container: card / inline-size;
3}
4
5.card-title {
6 /* Font size scales with container width */
7 font-size: clamp(1rem, 4cqi, 2.5rem);
8}
9
10.card-image {
11 /* Maintain aspect ratio relative to container */
12 aspect-ratio: 16 / 9;
13 width: 100%;
14 height: auto;
15}
16
17.card-body {
18 /* Padding scales with container */
19 padding: 2cqi;
20}
21
22.card-icon {
23 /* Size relative to container min dimension */
24 width: 8cqmin;
25 height: 8cqmin;
26}
preview
Container Query vs Media Query

Understanding when to use each approach is critical. Media queries respond to the viewport; container queries respond to a parent element. They serve different purposes and work best together.

AspectMedia QueryContainer Query
ReferenceViewport / screenNearest container
ContextGlobal layoutComponent-level
ReusabilityComponent depends on viewportComponent adapts to any context
Browser SupportUniversalModern browsers (Chrome 105+, Safari 16+, Firefox 110+)
Use casePage layout, sidebars, global breakpointsCards, widgets, panels, reusable components

info

Use media queries for your page-level grid and layout. Use container queries for components that need to adapt within that grid. They are complementary — not either/or.
cq-vs-mq.css
CSS
1/* Page layout — media queries */
2.layout {
3 display: grid;
4 grid-template-columns: 1fr;
5}
6
7@media (min-width: 768px) {
8 .layout {
9 grid-template-columns: 240px 1fr;
10 }
11}
12
13/* Component inside — container queries */
14.widget-container {
15 container: widget / inline-size;
16}
17
18@container widget (min-width: 300px) {
19 .widget { flex-direction: row; }
20}
21
22@container widget (max-width: 299px) {
23 .widget { flex-direction: column; }
24}
Container Query Examples

Here are practical patterns for building component-level responsive designs with container queries.

Responsive Card Component

responsive-card.css
CSS
1.card-container {
2 container: card / inline-size;
3}
4
5@container card (min-width: 450px) {
6 .card {
7 display: grid;
8 grid-template-columns: 200px 1fr;
9 gap: 20px;
10 }
11 .card-image {
12 aspect-ratio: auto;
13 height: 100%;
14 }
15 .card-cta {
16 align-self: end;
17 }
18}
19
20@container card (max-width: 449px) {
21 .card {
22 display: flex;
23 flex-direction: column;
24 }
25 .card-image {
26 aspect-ratio: 16 / 9;
27 width: 100%;
28 }
29 .card-cta {
30 width: 100%;
31 }
32}

Dashboard Widget Grid

dashboard-widgets.css
CSS
1.dashboard {
2 container: dashboard / inline-size;
3}
4
5@container dashboard (min-width: 900px) {
6 .widget-grid {
7 display: grid;
8 grid-template-columns: repeat(3, 1fr);
9 gap: 16px;
10 }
11}
12
13@container dashboard (600px <= inline-size < 900px) {
14 .widget-grid {
15 display: grid;
16 grid-template-columns: repeat(2, 1fr);
17 }
18}
19
20@container dashboard (max-width: 599px) {
21 .widget-grid {
22 display: flex;
23 flex-direction: column;
24 }
25}

Navigation with Container Queries

nav-cq.css
CSS
1.nav-container {
2 container: nav / inline-size;
3}
4
5@container nav (min-width: 600px) {
6 .nav-list {
7 display: flex;
8 gap: 24px;
9 }
10 .nav-toggle { display: none; }
11}
12
13@container nav (max-width: 599px) {
14 .nav-list {
15 display: none;
16 }
17 .nav-toggle {
18 display: block;
19 }
20}
preview
Nested Containers

Container queries resolve to the nearest ancestor with container-type. When containers are nested, a @container rule without a name queries the closest container ancestor.

nested-containers.css
CSS
1.outer {
2 container-type: inline-size;
3 container-name: outer;
4}
5
6.inner {
7 container-type: inline-size;
8 container-name: inner;
9}
10
11/* This queries the nearest container (inner) */
12@container (min-width: 300px) {
13 .child { color: #00FF41; }
14}
15
16/* This queries the outer container specifically */
17@container outer (min-width: 600px) {
18 .child { font-size: 1.5rem; }
19}
20
21/* Style queries — not yet widely supported */
22@container inner (style(--variant: compact)) {
23 .child { gap: 4px; }
24}
📝

note

When using named containers, the query looks up the DOM tree for the nearest ancestor with a matching container-name. If none is found, the query is ignored.
Browser Support

Container queries are supported in all major browsers as of 2024. The feature is stable and production-ready.

BrowserSupportVersion
Chrome105+
Edge105+
Firefox110+
Safari16+
$Blueprint — Engineering Documentation·Section ID: CSS-28·Revision: 1.0