Media queries respond to viewport size. Container queries respond to the parent element's size. That sounds like a small distinction. It changes how responsive components work.
With media queries, a card has one set of styles when the window is narrow and another when it is wide. But if that card appears in a sidebar (narrow) and a main column (wide) at the same viewport width, media queries cannot help. Both versions get the same styles because the viewport is the same.
Container queries fix this. The card adapts to its container, not the viewport. In the sidebar it stacks. In the main column it goes horizontal. Same component, different containers, different layouts. No JavaScript, no duplicated CSS, no workarounds.
Container Query Syntax
Two steps: define a container and write queries against it.
1. Define the container:
`css
.card-container {
container-type: inline-size;
container-name: card;
}
`
container-type: inline-size tells the browser to track this element's inline size (width in horizontal writing modes) for container queries. You can also use size (tracks both width and height) but inline-size is more common and has fewer side effects.
2. Write a container query:
`css
@container card (min-width: 400px) {
.card {
display: flex;
flex-direction: row;
}
}
@container card (max-width: 399px) {
.card {
display: flex;
flex-direction: column;
}
}
`
When the .card-container element is 400px or wider, the card displays horizontally. When it is narrower, the card stacks vertically. This happens regardless of the viewport width.
The container-name is optional. Without it, the query applies to the nearest ancestor with container-type:
`css
@container (min-width: 400px) {
.card { display: flex; }
}
`
Naming containers is recommended for clarity, especially when nesting containers.
Experiment with container layouts using the Grid Calculator to understand how different container widths affect your grid-based components.

Practical Component Patterns
Responsive card:
`css
.card-wrapper { container-type: inline-size; }
.card { display: grid; gap: 16px; }
@container (min-width: 500px) { .card { grid-template-columns: 200px 1fr; } }
@container (min-width: 700px) {
.card {
grid-template-columns: 300px 1fr;
gap: 24px;
}
}
`
Responsive navigation:
`css
.nav-container { container-type: inline-size; }
.nav { display: flex; flex-direction: column; }
@container (min-width: 600px) {
.nav {
flex-direction: row;
justify-content: space-between;
}
}
`
Adaptive sidebar widget:
`css
.sidebar { container-type: inline-size; }
@container (max-width: 250px) { .widget-title { font-size: 0.875rem; } .widget-chart { display: none; } .widget-value { font-size: 1.5rem; } }
@container (min-width: 251px) {
.widget-title { font-size: 1rem; }
.widget-chart { display: block; }
.widget-value { font-size: 2rem; }
}
`
These patterns create components that adapt to where they are placed, not just what device they are viewed on. Test these patterns alongside Flexbox layouts in the Flexbox Playground.
**Responsive card**: ```css .card-wrapper { container-type: inline-size; } .card { display: grid; gap: 16px; } @container (min-width: 500px) { .card { grid-template-columns: 200px 1fr; } } @container (min-width: 700px) { .card { grid-template-columns: 300px 1fr; gap: 24px; } } ``` **Responsive navigation**: ```css .nav-container { container-type: inline-size; } .nav { display: flex; flex-direction: column; } @container (min-width: 600px) { .nav { flex-direction: row; justify-content: space-between; } } ``` **Adaptive sidebar widget**: ```css .sidebar { container-type: inline-size; } @container (max-width: 250px) { .widget-title { font-size: 0.875rem; } .widget-chart { display: none; } .widget-value { font-size: 1.5rem; } } @container (min-width: 251px) { .widget-title { font-size: 1rem; } .widget-chart { display: block; } .widget-value { font-size: 2rem; } } ``` These patterns create components that adapt to where they are placed, not just what device they are viewed on.
Container Queries vs Media Queries
Both have their place. Here is when to use each:
Use container queries for: - Component-level responsive design (cards, widgets, navigation within a panel) - Reusable components that appear in different contexts - Layout changes that depend on available space, not viewport width - Design systems where components must be context-agnostic
Use media queries for: - Page-level layout changes (switching from sidebar to stacked layout) - Viewport-specific features (hiding elements on mobile, changing page margins) - Print styles - Reduced motion and color scheme preferences
Use both together:
`css
/ Page layout changes with media queries /
@media (min-width: 768px) {
.page { grid-template-columns: 300px 1fr; }
}
/ Component adaptation with container queries / .main-content { container-type: inline-size; }
@container (min-width: 500px) {
.article-card { grid-template-columns: 200px 1fr; }
}
`
The page layout switches from single-column to sidebar-plus-content at 768px viewport width. The article cards inside the content area adapt based on the content area's actual width, which changes when the sidebar appears. This separation of concerns is cleaner than trying to account for both with media queries alone.
Container Query Units
Container queries introduce new CSS units relative to the container's size:
cqw: 1% of the container's widthcqh: 1% of the container's heightcqi: 1% of the container's inline sizecqb: 1% of the container's block sizecqmin: the smaller of cqi and cqbcqmax: the larger of cqi and cqb
These are the container equivalents of viewport units (vw, vh). They enable fluid sizing relative to the container:
`css
.card-wrapper { container-type: inline-size; }
.card-title { font-size: clamp(1rem, 3cqi, 2rem); }
.card-image {
height: 30cqi;
}
`
The title font size scales with the container width, clamped between 1rem and 2rem. The image height is always 30% of the container width, maintaining a consistent aspect ratio regardless of where the card is placed.
Container query units are particularly useful for responsive typography and spacing within components, providing the same fluid scaling that viewport units provide at the page level.
Minify your container query CSS alongside the rest of your styles. The CSS Minifier handles @container rules correctly.

FAQ
Are container queries supported in all browsers?
Yes. Container queries (using container-type and @container) have been supported in Chrome 105+, Firefox 110+, Safari 16+, and Edge 105+ since late 2022/early 2023. Browser support is solid in 2026. No polyfill needed for modern browsers.
Do container queries replace media queries?
No. They complement each other. Media queries handle viewport-level and device-level responsive design. Container queries handle component-level responsive design. Most projects use both. Think of media queries as the page architect and container queries as the component architect.
What is the performance impact of container queries?
Minimal. The browser already calculates element sizes for layout. Container queries add a check against these sizes to apply styles. In benchmarks, the performance difference between container queries and equivalent media queries is negligible. Avoid deeply nested containers (5+ levels) as each level adds a layout calculation.
Can I use container queries with CSS Grid and Flexbox?
Absolutely. Container queries define when styles change. Grid and Flexbox define how the layout works. They are different axes of the same design system. A container query might switch a component from flex-direction: column to grid-template-columns: 1fr 1fr based on available width.
Markdown Table Generator: Build Clean Tables Without the Pain
Markdown tables are simple until the pipes and dashes stop lining up. Learn the syntax, alignment tricks, and a free tool that formats tables for you.
CSV to JSON: Convert Spreadsheet Data for APIs and Code
Turn a CSV export into clean JSON for APIs, imports, and scripts. Learn how the conversion works, common pitfalls with types and quotes, and a free tool.
JSON Guide: Format, Validate, and Convert JSON Files
JSON guide for developers: syntax rules, common parse errors, formatting and schema validation, plus how to convert between JSON and CSV files.
