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 :
.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 {
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 :
@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) :
.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 :
.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 :
@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
- Ajoutez
container-type: inline-sizeautour d’une carte ; vérifiez le contexte de containment dans DevTools. - Écrivez
@container (min-width: 24rem)pour passer de pile à deux colonnes. - Définissez
container-name: panelet ciblez avec@container panel (min-width: 30rem). - Dimensionnez un titre avec
cqiet redimensionnez seulement le parent (pas la fenêtre). - Gardez un
@mediasur la coque ; ne dupliquez pas cette logique dans la carte.
Erreurs courantes
@containersanscontainer-typesur 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(souventinline-size) ;container-nameoptionnel pour la clarté@container (min-width: …)/@container name (…)pour restyler les descendantscqi/cqwquand les longueurs doivent suivre le conteneur- Suite Modern Toolkit : feature queries (
@supports) — styles selon les capacités du navigateur
🧠 Testez Vos Connaissances
Testez Vos Connaissances
Mettez-vous au défi avec ce quiz interactif et voyez à quel point vous comprenez le sujet
📝 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