CSS Container Queries

Basic Syntax

/* 1. Define container on parent */ .card-wrapper { container-type: inline-size; /* or: size | normal */ } /* 2. Named container */ .sidebar { container-type: inline-size; container-name: sidebar; /* shorthand: */ container: sidebar / inline-size; } /* 3. Query inside container */ @container (min-width: 400px) { .card { display: grid; grid-template-columns: 1fr 2fr; } } /* 4. Query named container */ @container sidebar (min-width: 300px) { .widget { flex-direction: row; } }

Practical Example — Responsive Card

.card-grid { container-type: inline-size; } .card { /* Default: stacked layout */ display: grid; grid-template-rows: auto 1fr auto; gap: 12px; padding: 16px; } .card__image { width: 100%; } .card__title { font-size: 1rem; } /* When container is wide enough: side-by-side */ @container (min-width: 480px) { .card { grid-template-columns: 200px 1fr; grid-template-rows: auto auto; align-items: start; } .card__image { grid-row: 1 / -1; height: 100%; object-fit: cover; } .card__title { font-size: 1.25rem; } } @container (min-width: 700px) { .card__title { font-size: 1.5rem; } }

container-type Values

ValueDescription
inline-sizeQuery based on container's inline dimension (width in horizontal writing)
sizeQuery based on both inline and block dimensions
normalNo containment, but can be named (for style queries)

Container vs Media Queries

AspectMedia QueriesContainer Queries
Based onViewport width/heightContainer element size
Reusable componentsHard — depends on layout contextEasy — component adapts to its container
Sidebar vs main contentNeeds different class per contextOne class, adapts automatically
Browser support100%90%+ (Chrome 105+, FF 110+, Safari 16+)