Learn CSS Container Queries to style elements based on their container's size rather than the viewport. Understand container-type, container-name, @container rules, and container query units.
Media queries let you respond to the viewport size, but what if a component needs to adapt based on the size of its container? A card component might appear in a wide main area or a narrow sidebar, and it should look good in both places regardless of viewport width.
This is exactly what Container Queries solve. They let you apply styles based on the dimensions of a parent container rather than the viewport.
/* 1. Define a containment context */
.card-wrapper {
container-type: inline-size;
}
/* 2. Query the container's size */
@container (min-width: 400px) {
.card {
display: flex;
flex-direction: row;
}
}The element with container-type becomes the container that descendant @container rules query against. This is a fundamental shift in responsive design: components can now be self-responsive rather than relying on the page layout to dictate their appearance.
<style>
/* Define the container */
.panel {
container-type: inline-size;
container-name: panel;
padding: 16px;
background: #0f172a;
border: 1px solid #334155;
}
/* Base card style */
.card {
padding: 12px;
background: #1e293b;
border-radius: 8px;
}
.card-title { font-size: 16px; color: white; }
.card-body { font-size: 14px; color: #94a3b8; }
/* When the panel container is wide enough */
@container panel (min-width: 300px) {
.card {
display: flex;
gap: 16px;
align-items: center;
}
.card-title { font-size: 20px; }
}
</style>
<div class="panel">
<div class="card">
<div class="card-title">Title</div>
<div class="card-body">Adapts to container width.</div>
</div>
</div>The container-type property defines what kind of containment is established:
inline-size — Enables queries on the container's inline (width) dimension. This is the most common value.size — Enables queries on both width and height. Use this when you also need to query the container's block (height) dimension.normal — The default. The element is not a query container.You can also name containers with container-name and target them specifically in your queries:
.sidebar { container-type: inline-size; container-name: sidebar; }
.main { container-type: inline-size; container-name: main; }
@container sidebar (max-width: 200px) {
.widget { font-size: 12px; }
}Container Queries also introduce container query units:
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 size@container (min-width: 300px) {
.card-title { font-size: 5cqi; } /* scales with container */
}What is the key difference between media queries and container queries?