Salta al contenuto principale

06 - CSS Container Queries: Componenti Veramente Responsivi

CSS Container Queries: Componenti Veramente Responsivi Per anni, il responsive design ha significato: "adatta il layout al viewport".

Cosa ne pensi di questo articolo?

06 - CSS Container Queries: Componenti Veramente Responsivi
Core Web VitalsFoto:AS PhotographyPexels

In Breve

CSS Container Queries: Componenti Veramente Responsivi Per anni, il responsive design ha significato: "adatta il layout al viewport".

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 @container per 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 container
  • cqh: 1% dell'altezza del container
  • cqi: 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 cqb
  • cqmax: 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.

Prova Questi Strumenti

Strumenti gratuiti correlati a questo argomento.

Commenti

Caricamento commenti...

Accedi per commentare

Discuti questo articolo nella community

Unisciti al gruppo Telegram per discutere con altri sviluppatori, fare domande e condividere le tue esperienze.

Ti è piaciuto questo articolo?

Esplora altri contenuti sul blog o scopri i miei progetti