CSS Container Queries: Componenti Veramente Responsivi
Per anni, il responsive design ha significato: "adatta il layout al viewport".
Un componente card con @media (max-width: 768px) sa quanto e largo
lo schermo, ma non sa quanto spazio ha effettivamente a disposizione nel suo
contesto. Metti quella card in una sidebar stretta e si comporta come se fosse
su mobile, anche se lo schermo e un 27" desktop. Mettila nel contenuto principale
e si comporta come desktop anche se quel contenitore e piu stretto di uno smartphone.
Le CSS Container Queries risolvono questo problema alla radice: un componente puo reagire alle dimensioni del proprio contenitore, non del viewport. Con supporto browser superiore all'88% in Baseline 2025 (Chrome 105+, Firefox 110+, Safari 16+), questa tecnica e pronta per la produzione.
Cosa Imparerai
- La differenza fondamentale tra Media Queries e Container Queries
- Come definire un containment context con
container-type - La sintassi
@containerper le query - Container size queries: inline-size, block-size
- Container style queries: query basate su custom properties
- Named containers per query gerarchiche
- Come integrare le container queries in Angular, React e Vue
Il Problema con le Media Queries
Le media queries interrogano le caratteristiche del viewport: la larghezza dello schermo, l'orientation, il color scheme. Questo funziona quando il layout e semplice e un componente occupa sempre una larghezza prevedibile. Ma nei design system moderni, lo stesso componente viene riusato in contesti radicalmente diversi:
- Una card prodotto nella homepage (3 colonne su desktop)
- La stessa card nella sidebar "prodotti correlati" (1 colonna stretta)
- La stessa card in un modal fullscreen (2 colonne)
- La stessa card nella pagina di ricerca (variabile in base ai filtri attivi)
Con media queries, devi conoscere in anticipo il contesto di ogni utilizzo e scrivere selettori CSS specifici per ogni caso. Con container queries, il componente e autonomo: si adatta da solo al proprio spazio disponibile.
Definire un Container
Per usare le container queries, il primo passo e dichiarare quale elemento e il
"container" che verra interrogato. Si fa con la proprieta container-type:
/* Crea un container che risponde alla larghezza (inline-size) */
.card-wrapper {
container-type: inline-size;
}
/* Crea un container che risponde sia a larghezza che altezza */
.card-wrapper {
container-type: size;
}
/* Dai un nome al container per query gerarchiche */
.card-wrapper {
container-type: inline-size;
container-name: card;
}
/* Shorthand */
.card-wrapper {
container: card / inline-size;
}
Una volta che un elemento ha container-type, tutti i suoi discendenti
possono usare @container per interrogarne le dimensioni.
La Sintassi @container
La sintassi e identica alle media queries, ma invece di interrogare il viewport, interroga il container piu vicino con un containment context:
.card {
/* Layout default: verticale, compatto */
display: grid;
grid-template-areas:
"image"
"content";
gap: 12px;
}
.card__image {
aspect-ratio: 16 / 9;
object-fit: cover;
border-radius: 8px 8px 0 0;
}
/* Quando il container e largo almeno 400px: layout orizzontale */
@container (min-width: 400px) {
.card {
grid-template-areas: "image content";
grid-template-columns: 200px 1fr;
}
.card__image {
aspect-ratio: 1;
border-radius: 8px 0 0 8px;
}
}
/* Quando il container e largo almeno 600px: layout espanso */
@container (min-width: 600px) {
.card {
grid-template-columns: 280px 1fr;
gap: 24px;
padding: 24px;
}
.card__title {
font-size: 1.5rem;
}
}
/* Range syntax (CSS Level 4) - piu leggibile */
@container (200px <= width <= 400px) {
.card {
/* stile per range specifico */
}
}
Named Containers: Query Gerarchiche
Quando hai container annidati, puoi nominare i container per interrogare un antenato specifico invece del piu vicino:
<!-- HTML struttura -->
<main class="layout" style="container: layout / inline-size">
<aside class="sidebar" style="container: sidebar / inline-size">
<div class="widget">
<!-- Questo widget puo interrogare sia "sidebar" che "layout" -->
</div>
</aside>
</main>
/* Query sul container "sidebar" (il piu vicino) */
@container sidebar (min-width: 300px) {
.widget { display: flex; }
}
/* Query sul container "layout" (l'antenato nominato) */
@container layout (min-width: 1200px) {
.widget { max-width: 400px; }
}
Container Style Queries: La Feature Nascosta
Oltre alle size queries, le container queries supportano anche le style queries: query basate sui valori delle CSS custom properties del container. Questa feature, supportata in Chrome 111+ e Safari 17.4+, apre possibilita completamente nuove per theming e varianti di componenti.
/* Definisci una custom property sul container */
.card-wrapper {
container-type: style;
/* La variante del componente viene comunicata via custom property */
--card-variant: featured;
}
/* Il componente si adatta alla variante del container */
@container style(--card-variant: featured) {
.card {
border: 2px solid var(--color-accent);
background: var(--color-accent-subtle);
}
.card__badge {
display: block; /* mostra il badge "In evidenza" */
}
}
@container style(--card-variant: compact) {
.card {
padding: 8px;
font-size: 0.875rem;
}
.card__image {
display: none; /* nasconde l'immagine in modalita compatta */
}
}
Questo pattern permette di comunicare contesto semantico dal contenitore al componente senza classi CSS aggiuntive o JavaScript, mantenendo l'incapsulamento.
Unita di Misura dei Container: cqw, cqh, cqi, cqb
Con le container queries arrivano anche nuove unita di misura relative al container:
cqw: 1% della larghezza del containercqh: 1% dell'altezza del containercqi: 1% dell'inline size del container (= cqw per layout LTR)cqb: 1% del block size del container (= cqh)cqmin: il piu piccolo tra cqi e cqbcqmax: il piu grande tra cqi e cqb
/* Tipografia fluida relativa al container */
.card__title {
/* Scala da 16px a 24px in base alla larghezza del container */
font-size: clamp(1rem, 4cqi, 1.5rem);
}
/* Padding proporzionale al container */
.card {
padding: 5cqi;
}
/* Gap che si adatta */
.card__grid {
display: grid;
gap: clamp(8px, 2cqi, 24px);
}
Container Queries in Angular, React e Vue
Angular: Componenti Container-Aware
/* card.component.scss */
:host {
display: block;
container-type: inline-size;
container-name: card-host;
}
.card {
display: grid;
grid-template-areas: "image" "content";
gap: 12px;
}
@container card-host (min-width: 400px) {
.card {
grid-template-areas: "image content";
grid-template-columns: 180px 1fr;
}
}
// card.component.ts
@Component({
selector: 'app-card',
templateUrl: './card.component.html',
styleUrls: ['./card.component.scss'],
// :host come container - nessun JS necessario per il responsive
host: { class: 'card-container' }
})
export class CardComponent {
@Input() product!: Product;
}
React: CSS Modules con Container Queries
/* card.module.css */
.wrapper {
container-type: inline-size;
container-name: card;
}
.card {
display: grid;
gap: 12px;
}
@container card (min-width: 400px) {
.card {
grid-template-columns: 180px 1fr;
}
}
// Card.tsx
import styles from './card.module.css';
export function Card({ product }: { product: Product }) {
return (
<div className={styles.wrapper}>
<article className={styles.card}>
<img src={product.image} alt={product.name} />
<div>
<h3>{product.name}</h3>
<p>{product.description}</p>
</div>
</article>
</div>
);
}
Container Queries vs Media Queries: Quando Usare Cosa
| Scenario | Scelta Ottimale | Motivo |
|---|---|---|
| Layout globale della pagina | Media Queries | Il layout dipende dal viewport |
| Componenti riusabili | Container Queries | Il componente deve adattarsi al suo contesto |
| Design system tokens | Entrambi | Viewport per breakpoint, container per varianti |
| Dark/light mode | Media Queries | prefers-color-scheme e una media feature |
| Sidebar dinamica | Container Queries | Il contenuto si adatta alla sidebar aperta/chiusa |
| Print styling | Media Queries | @media print e una media query |
Pattern Anti: Errori Comuni con Container Queries
Errore #1: Container che Interroga se Stesso
Un elemento con container-type non puo interrogare se stesso con
@container - deve essere un discendente ad essere modificato.
Non definire mai un container e una regola @container sullo stesso
selettore.
Errore #2: container-type: size senza Altezza Definita
container-type: size richiede che il container abbia una dimensione
definita sia in larghezza che in altezza. Se usi size su un container
senza altezza esplicita, le query height e cqh
non funzioneranno come atteso. Usa inline-size nella maggior parte
dei casi.
Next Steps
Hai ora i componenti veramente responsivi grazie alle container queries. Il prossimo articolo della serie esplora la CSS Anchor Positioning API, che permette di implementare tooltip, dropdown e popover senza una singola riga di JavaScript: un'altra tecnica che avvicina CSS alla potenza dichiarativa che i developer aspettavano da anni.
Conclusioni
Le CSS Container Queries cambiano fondamentalmente il modo in cui costruiamo componenti responsivi. Invece di un sistema di breakpoint globale che ogni componente deve conoscere e rispettare, ogni componente diventa autonomo e si adatta al proprio contesto. Questo porta a codice piu manutenibile, design system veramente componibili e meno casi edge da gestire manualmente.
Con supporto browser superiore all'88%, le container queries sono pronte per la produzione oggi. Il modo migliore per iniziare e identificare i componenti del tuo design system che vengono usati in contesti multipli - tipicamente card, list item, media object - e convertirli progressivamente al nuovo paradigma.

Commenti
Caricamento commenti...
Accedi per commentare