Chargement...

Container queries CSS

Le nesting regroupe les sélecteurs du composant. Les media queries observent toujours le viewport. Les container queries posent une autre question : quelle est la largeur de cette boîte parente ? Une même fiche produit reste compacte dans un rail étroit et s’ouvre dans la colonne principale — même si la fenêtre du navigateur n’a pas bougé.

Pourquoi le viewport ne suffit pas

Un layout place souvent le même composant dans des emplacements inégaux : un rail latéral de 16rem et une zone principale fluide. Les deux partagent la largeur du viewport, donc @media (min-width: …) se déclenche pareil. Il faut des styles liés au conteneur autour de la carte, pas à tout l’écran.

Créer un contexte de containment

Choisissez le parent qui doit signaler sa taille. Définissez container-type — en général inline-size pour interroger la taille en ligne du parent (largeur en écriture horizontale) sans imposer un containment de taille sur les deux axes :

Turn a rail into a size container

css
.rail {
container-type: inline-size;
container-name: rail;
width: 16rem;
padding: 1rem;
background: #f8fafc;
}

.stage {
container-type: inline-size;
container-name: stage;
flex: 1;
min-width: 0;
padding: 1.25rem;
}

Sans container-type, @container n’a rien de fiable à mesurer. container-name est optionnel mais puissant quand plusieurs ancêtres sont conteneurs — vous visez l’un par son nom.

Interroger le conteneur avec @container

Après la mise en place, enveloppez les règles dans @container avec une condition de taille. Les descendants réagissent quand cette boîte correspond — pas seulement quand le viewport change :

Product card reacts to its parent width

css
.product-card {
display: grid;
gap: 0.75rem;
padding: 1rem;
border: 1px solid #e2e8f0;
border-radius: 0.75rem;
background: #fff;
}

.product-card .media {
aspect-ratio: 16 / 10;
border-radius: 0.5rem;
background: #cbd5e1;
}

.product-card .meta {
font-size: 0.875rem;
color: #64748b;
}

@container (min-width: 28rem) {
.product-card {
grid-template-columns: 10rem 1fr;
align-items: center;
}

.product-card .title {
font-size: 1.25rem;
}
}

Dans un .rail étroit, la pile une colonne reste. Le même HTML dans un .stage large débloque deux colonnes — même markup, même viewport, largeur de conteneur différente.

Conteneurs nommés

Si des conteneurs imbriqués brouillent quelle boîte est consultée, indiquez le nom après @container :

Target a named containment context

css
@container stage (min-width: 36rem) {
.product-card {
grid-template-columns: 12rem 1fr auto;
gap: 1.25rem;
}

.product-card .buy {
justify-self: end;
}
}

@container rail (max-width: 18rem) {
.product-card .meta {
display: none;
}
}

@container stage (…) ne regarde que l’ancêtre nommé stage. Les règles serrées du rail n’entrent pas en conflit avec celles du stage quand les deux enveloppent le même markup.

Unités de container query

Avec un contexte de containment, des longueurs comme cqi (1 % de la taille en ligne du conteneur de requête) et cqw (1 % de sa largeur) font évoluer typo et espacements avec le parent, pas le viewport (vi / vw) :

Type that tracks the container

css
.product-card .title {
font-size: clamp(1rem, 0.85rem + 2.5cqi, 1.5rem);
}

.product-card {
padding: clamp(0.75rem, 2.5cqi, 1.5rem);
}

Associez-les à var() et clamp() des leçons Modern Toolkit précédentes. Les unités conteneur mesurent le contexte utilisé pour la requête — idéal pour des widgets réutilisables.

Conteneur vs media — qui fait quoi ?

📊 Container queries vs media queries

Question posée Préférer Outil typique
Quelle est la largeur du viewport ? Coque de page, nav, page multi-colonnes @media (min-width: …)
Quelle est la largeur de ce parent autour du composant ? Cartes, widgets, embeds dans des emplacements inégaux @container (min-width: …) après container-type
Les deux ? Souvent oui MQ pour la page ; CQ pour le composant dans l’emplacement

Deux emplacements, un composant

Un petit schéma montre l’intérêt — deux conteneurs, une classe carte :

Sidebar rail and main stage share one card

css
.page {
display: flex;
gap: 1rem;
align-items: start;
}

.rail {
container-type: inline-size;
container-name: rail;
width: 16rem;
}

.stage {
container-type: inline-size;
container-name: stage;
flex: 1;
min-width: 0;
}

/* Same .product-card class in both slots — @container rules above decide layout */

Inutile de forker .product-card--sidebar et .product-card--main juste pour la largeur d’emplacement. L’emplacement signale sa taille ; la carte écoute.

Combiner media de page et conteneurs composant

Gardez les requêtes viewport pour la page (replier la nav, coque en une colonne). Réservez les container queries aux décisions composant dans l’emplacement que la page lui donne :

Viewport for the page, container for the card

css
@media (max-width: 40rem) {
.page {
flex-direction: column;
}

.rail {
width: auto;
}
}

@container (min-width: 28rem) {
.product-card {
grid-template-columns: 10rem 1fr;
}
}

Sur un petit téléphone la page s’empile ; sur un grand écran le rail peut rester étroit et le stage large — seules les container queries expriment proprement cet écart.

À vous de jouer

  1. Ajoutez container-type: inline-size autour d’une carte ; vérifiez le contexte de containment dans DevTools.
  2. Écrivez @container (min-width: 24rem) pour passer de pile à deux colonnes.
  3. Définissez container-name: panel et ciblez avec @container panel (min-width: 30rem).
  4. Dimensionnez un titre avec cqi et redimensionnez seulement le parent (pas la fenêtre).
  5. Gardez un @media sur la coque ; ne dupliquez pas cette logique dans la carte.

Erreurs courantes

  • @container sans container-type sur un ancêtre — rien d’utile à mesurer
  • Remplacer toutes les media queries par des container queries — la coque reste à @media
  • Trois conteneurs imbriqués sans savoir quelle largeur gagne — nommez et ciblez explicitement
  • Copier les breakpoints viewport (48rem) dans chaque widget — réglez sur l’emplacement, pas le catalogue d’appareils
  • Confondre nesting (&, sélecteurs imbriqués) et containment — le nesting organise ; les container queries mesurent des boîtes

Synthèse

  • Les container queries stylent selon la taille du parent, pas seulement le viewport
  • container-type (souvent inline-size) ; container-name optionnel pour la clarté
  • @container (min-width: …) / @container name (…) pour restyler les descendants
  • cqi / cqw quand les longueurs doivent suivre le conteneur
  • Suite Modern Toolkit : feature queries (@supports) — styles selon les capacités du navigateur

🧠 Testez Vos Connaissances

Prêt à Commencer

Testez Vos Connaissances

Mettez-vous au défi avec ce quiz interactif et voyez à quel point vous comprenez le sujet

❓
6
Questions
🎯
70%
Pour Réussir
♾️
∞
Temps
🔄
∞
Tentatives

📝 Instructions

  • Lisez chaque question attentivement
  • Sélectionnez la meilleure réponse pour chaque question
  • Vous pouvez refaire le quiz autant de fois que vous le souhaitez
  • Votre progression sera affichée en haut