From container-queries
Comprehensive container query patterns library. Use when searching for responsive component patterns, container query syntax, or modern CSS responsive design techniques.
How this skill is triggered — by the user, by Claude, or both
Slash command
/container-queries:container-query-patternsThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
A comprehensive searchable reference for CSS Container Queries, container units, and modern component-based responsive design patterns.
A comprehensive searchable reference for CSS Container Queries, container units, and modern component-based responsive design patterns.
| Pattern | Syntax | Use Case |
|---|---|---|
| Inline Size | container-type: inline-size; | Most common - width-based queries |
| Block Size | container-type: block-size; | Height-based queries (rare) |
| Size | container-type: size; | Width AND height queries |
| Normal | container-type: normal; | No containment (default) |
| Named Container | container-name: sidebar; | Target specific containers |
| Shorthand | container: sidebar / inline-size; | Name + type together |
/* Basic width queries */
@container (min-width: 400px) { }
@container (max-width: 600px) { }
@container (width >= 400px) { } /* Modern syntax */
@container (width < 600px) { }
/* Range queries */
@container (min-width: 400px) and (max-width: 800px) { }
@container (400px <= width <= 800px) { } /* Modern range */
/* Named container queries */
@container sidebar (min-width: 300px) { }
@container card-container (width > 500px) { }
/* Orientation queries */
@container (orientation: portrait) { }
@container (orientation: landscape) { }
/* Aspect ratio queries */
@container (aspect-ratio > 16/9) { }
@container (aspect-ratio: 1/1) { } /* Square */
/* Height queries (with size or block-size) */
@container (min-height: 400px) { }
@container (height > 600px) { }
| Unit | Description | Example | Use Case |
|---|---|---|---|
| cqw | 1% of container width | width: 50cqw; | Horizontal sizing |
| cqh | 1% of container height | height: 30cqh; | Vertical sizing |
| cqi | 1% of container inline size | font-size: 5cqi; | Inline dimension (width in LTR) |
| cqb | 1% of container block size | padding-block: 2cqb; | Block dimension (height in LTR) |
| cqmin | 1% of smaller dimension | padding: 2cqmin; | Uniform spacing |
| cqmax | 1% of larger dimension | margin: 1cqmax; | Scale with larger axis |
/* Responsive typography */
.title {
font-size: clamp(1rem, 5cqi, 3rem);
}
/* Responsive spacing */
.card {
padding: clamp(0.5rem, 3cqi, 2rem);
gap: max(0.5rem, 2cqi);
}
/* Responsive grid */
.grid {
grid-template-columns: repeat(auto-fit, minmax(min(100%, 25cqi), 1fr));
}
/* Responsive border radius */
.element {
border-radius: clamp(0.25rem, 1cqi, 1rem);
}
Use Case: Card that changes from vertical stack to horizontal layout to overlay based on container width.
.card-container {
container-type: inline-size;
container-name: card;
}
/* Mobile: Vertical stack (< 400px) */
@container card (max-width: 399px) {
.card {
display: flex;
flex-direction: column;
}
.card__image {
width: 100%;
aspect-ratio: 16/9;
}
.card__content {
padding: 1rem;
}
}
/* Tablet: Horizontal layout (400px - 699px) */
@container card (min-width: 400px) and (max-width: 699px) {
.card {
display: grid;
grid-template-columns: 200px 1fr;
}
.card__image {
height: 100%;
object-fit: cover;
}
.card__content {
padding: 1.5rem;
}
}
/* Desktop: Overlay layout (≥ 700px) */
@container card (min-width: 700px) {
.card {
position: relative;
min-height: 400px;
}
.card__image {
position: absolute;
inset: 0;
width: 100%;
height: 100%;
object-fit: cover;
}
.card__content {
position: absolute;
bottom: 0;
left: 0;
right: 0;
padding: 2rem;
background: linear-gradient(to top, rgba(0,0,0,0.9), transparent);
color: white;
}
}
Use Case: Navigation that switches from hamburger menu to full horizontal menu.
.nav-container {
container-type: inline-size;
}
/* Compact: Hamburger menu */
@container (max-width: 600px) {
.nav__toggle {
display: block;
}
.nav__list {
position: absolute;
top: 100%;
left: 0;
right: 0;
background: white;
max-height: 0;
overflow: hidden;
transition: max-height 0.3s;
}
.nav__list.open {
max-height: 500px;
}
.nav__item {
display: block;
padding: 1rem;
border-bottom: 1px solid #e5e7eb;
}
}
/* Full: Horizontal menu */
@container (min-width: 601px) {
.nav__toggle {
display: none;
}
.nav__list {
display: flex;
gap: 1rem;
}
.nav__item {
padding: 0.5rem 1rem;
}
}
Use Case: Grid that adjusts column count based on container width.
.grid-container {
container-type: inline-size;
}
/* Auto-responsive grid */
.grid {
display: grid;
gap: 1rem;
}
@container (max-width: 499px) {
.grid {
grid-template-columns: 1fr;
}
}
@container (min-width: 500px) and (max-width: 799px) {
.grid {
grid-template-columns: repeat(2, 1fr);
}
}
@container (min-width: 800px) and (max-width: 1099px) {
.grid {
grid-template-columns: repeat(3, 1fr);
}
}
@container (min-width: 1100px) {
.grid {
grid-template-columns: repeat(4, 1fr);
}
}
/* Alternative: CSS-only auto-responsive */
.grid-auto {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(min(100%, 250px), 1fr));
gap: 1rem;
}
Use Case: Text size scales with container size using container units.
.text-container {
container-type: inline-size;
}
.heading {
font-size: clamp(1.5rem, 5cqi, 3rem);
line-height: calc(1.2 + 0.1cqi);
}
.body-text {
font-size: clamp(0.875rem, 2cqi + 0.5rem, 1.125rem);
line-height: calc(1.5 + 0.1cqi);
}
.caption {
font-size: clamp(0.75rem, 1.5cqi, 0.9375rem);
}
Use Case: Table that converts to card-based layout on small containers.
.table-container {
container-type: inline-size;
}
/* Mobile: Card layout */
@container (max-width: 600px) {
table {
display: block;
}
thead {
display: none;
}
tbody, tr, td {
display: block;
}
tr {
margin-bottom: 1rem;
border: 1px solid #e5e7eb;
border-radius: 0.5rem;
padding: 1rem;
}
td {
position: relative;
padding: 0.5rem 0 0.5rem 50%;
}
td::before {
content: attr(data-label);
position: absolute;
left: 0;
width: 45%;
font-weight: 600;
}
}
/* Desktop: Standard table */
@container (min-width: 601px) {
table {
width: 100%;
border-collapse: collapse;
}
th, td {
padding: 0.75rem;
text-align: left;
border-bottom: 1px solid #e5e7eb;
}
thead {
background: #f9fafb;
}
}
.layout {
container-type: inline-size;
display: grid;
}
@container (max-width: 768px) {
.layout {
grid-template-columns: 1fr;
}
.sidebar {
order: 2;
}
.main {
order: 1;
}
}
@container (min-width: 769px) {
.layout {
grid-template-columns: 300px 1fr;
}
}
@container (min-width: 1200px) {
.layout {
grid-template-columns: 350px 1fr 250px;
}
}
.feature-card-container {
container-type: inline-size;
}
@container (max-width: 350px) {
.feature {
text-align: center;
}
.feature__icon {
margin: 0 auto 1rem;
width: 48px;
height: 48px;
}
.feature__title {
font-size: 1rem;
}
}
@container (min-width: 351px) {
.feature {
display: flex;
gap: 1rem;
text-align: left;
}
.feature__icon {
flex-shrink: 0;
width: 64px;
height: 64px;
}
.feature__title {
font-size: 1.25rem;
}
}
.product-container {
container-type: inline-size;
}
/* Compact: Stacked actions */
@container (max-width: 280px) {
.product__actions {
display: flex;
flex-direction: column;
gap: 0.5rem;
}
.product__button {
width: 100%;
font-size: 0.875rem;
}
}
/* Medium: Horizontal actions */
@container (min-width: 281px) and (max-width: 400px) {
.product__actions {
display: flex;
gap: 0.5rem;
}
.product__button {
flex: 1;
font-size: 0.9375rem;
}
}
/* Large: Full layout with icons */
@container (min-width: 401px) {
.product__actions {
display: grid;
grid-template-columns: 1fr auto auto;
gap: 1rem;
}
.product__button {
padding: 0.75rem 1.5rem;
font-size: 1rem;
}
.product__button::before {
content: attr(data-icon);
margin-right: 0.5rem;
}
}
.holy-grail {
container-type: inline-size;
display: grid;
min-height: 100vh;
}
@container (max-width: 768px) {
.holy-grail {
grid-template-areas:
"header"
"main"
"left"
"right"
"footer";
grid-template-columns: 1fr;
}
}
@container (min-width: 769px) {
.holy-grail {
grid-template-areas:
"header header header"
"left main right"
"footer footer footer";
grid-template-columns: 200px 1fr 200px;
grid-template-rows: auto 1fr auto;
}
}
@container (min-width: 1200px) {
.holy-grail {
grid-template-columns: 250px 1fr 300px;
}
}
.pancake {
container-type: inline-size;
display: grid;
}
@container (max-width: 600px) {
.pancake {
grid-template-columns: 1fr;
}
}
@container (min-width: 601px) {
.pancake {
grid-template-columns: minmax(150px, 25%) 1fr;
}
}
@container (min-width: 1000px) {
.pancake {
grid-template-columns: minmax(200px, 20%) 1fr minmax(200px, 20%);
}
}
.ram-grid-container {
container-type: inline-size;
}
.ram-grid {
display: grid;
gap: 1rem;
}
@container (max-width: 500px) {
.ram-grid {
grid-template-columns: repeat(auto-fit, minmax(min(100%, 150px), 1fr));
}
}
@container (min-width: 501px) {
.ram-grid {
grid-template-columns: repeat(auto-fit, minmax(min(100%, 250px), 1fr));
}
}
@container (min-width: 1000px) {
.ram-grid {
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
}
}
/* ✅ Good: Minimal containment */
.efficient-container {
container-type: inline-size; /* Only inline dimension */
contain: layout style; /* Explicit containment */
}
/* ❌ Avoid: Over-containment */
.inefficient-container {
container-type: size; /* Both dimensions - more expensive */
contain: strict; /* Too restrictive */
}
/* ✅ Good: Group related changes */
@container (min-width: 400px) {
.card,
.card__header,
.card__body {
/* Apply changes together */
padding: 1.5rem;
}
}
/* ❌ Avoid: Repeated queries */
@container (min-width: 400px) {
.card { padding: 1.5rem; }
}
@container (min-width: 400px) {
.card__header { padding: 1.5rem; }
}
@container (min-width: 400px) {
.card__body { padding: 1.5rem; }
}
/* ✅ Good: Cache container unit calculations */
.container {
container-type: inline-size;
--container-padding: clamp(1rem, 3cqi, 3rem);
--container-gap: max(0.5rem, 2cqi);
}
.content {
padding: var(--container-padding);
gap: var(--container-gap);
}
/* ❌ Avoid: Repeated calculations */
.content {
padding: clamp(1rem, 3cqi, 3rem);
gap: max(0.5rem, 2cqi);
}
.other-content {
padding: clamp(1rem, 3cqi, 3rem); /* Recalculated */
}
/* Base styles (all browsers) */
.component {
padding: 1rem;
font-size: 1rem;
}
/* Container queries (modern browsers) */
@supports (container-type: inline-size) {
.component-wrapper {
container-type: inline-size;
}
@container (min-width: 400px) {
.component {
padding: 2rem;
font-size: 1.25rem;
}
}
}
/* Fallback: Media queries */
@media (min-width: 768px) {
.card {
display: grid;
grid-template-columns: 200px 1fr;
}
}
/* Enhancement: Container queries */
@supports (container-type: inline-size) {
.card-container {
container-type: inline-size;
}
@container (min-width: 400px) {
.card {
display: grid;
grid-template-columns: 200px 1fr;
}
}
}
/* Original code with container queries */
.card-wrapper {
container-type: inline-size;
}
@container (min-width: 30em) {
.card {
display: grid;
}
}
/* PostCSS transpiles to fallback */
.card-wrapper {
container-type: inline-size;
}
.card-wrapper[data-cq="30em"] .card {
display: grid;
}
Symptoms: Styles not applying when container resizes.
Solutions:
container-type is set on parent/* ✅ Correct */
.parent {
container-type: inline-size;
}
@container (min-width: 400px) {
.child {
display: grid;
}
}
/* ❌ Wrong: Missing container-type */
@container (min-width: 400px) {
.child {
display: grid;
}
}
Symptoms: Styles don't apply when using container-name.
Solutions:
container-name is set before @container rule/* ✅ Correct */
.parent {
container-name: sidebar;
}
@container sidebar (min-width: 300px) {
.content { }
}
/* ❌ Wrong: Name mismatch */
.parent {
container-name: sidebar;
}
@container side-bar (min-width: 300px) {
.content { }
}
Symptoms: Container units (cqi, cqw) not responding to size changes.
Solutions:
container-type setcqi for inline, cqb for block)/* ✅ Correct */
.parent {
container-type: inline-size;
width: 100%; /* Allow container to resize */
}
.child {
font-size: 5cqi;
}
/* ❌ Wrong: Fixed width prevents scaling */
.parent {
container-type: inline-size;
width: 500px; /* Fixed width */
}
Symptoms: Janky animations, slow rendering.
Solutions:
inline-size instead of size when possiblecontain: layout style to containers/* ✅ Optimized */
.container {
container-type: inline-size;
contain: layout style;
}
@container (min-width: 400px) {
.element-1,
.element-2,
.element-3 {
/* Batched changes */
}
}
| Browser | Version | Support |
|---|---|---|
| Chrome/Edge | 105+ | ✅ Full support |
| Safari | 16+ | ✅ Full support |
| Firefox | 110+ | ✅ Full support |
| Opera | 91+ | ✅ Full support |
Note: Always test with @supports (container-type: inline-size) for progressive enhancement.
✅ Use Container Queries When:
❌ Use Media Queries When:
inline-size over size@supportscontain property for performanceCreates, edits, and optimizes skills for Claude Code, including drafting, evaluating with test prompts, iterating on performance, and improving skill descriptions for better triggering accuracy.
npx claudepluginhub ehssanatassi/ui-marketplace --plugin container-queries