</> HTML5Advent
ENFRESDEITPT

// css · Web Platform Advent #8

Container queries CSS : styler un composant selon son conteneur, pas la fenêtre

container-type, @container et container-name expliqués. En quoi les container queries diffèrent des media queries et pourquoi elles rendent les composants vraiment réutilisables.

Icônes plates d'un écran de bureau, d'une tablette, d'un portable et d'un téléphone de tailles différentes

Les container queries permettent à un élément de réagir à la taille de son conteneur parent plutôt qu'à celle de la fenêtre entière. C'est la pièce manquante qui rend enfin un composant réutilisable : une même carte peut s'agencer d'une façon dans une barre latérale étroite et autrement dans une colonne principale large — sur la même page, à la même largeur d'écran.

Pourquoi les media queries ne suffisaient pas

Une media query pose une seule question : quelle est la largeur de la fenêtre ? Mais un composant ne connaît pas la largeur de la fenêtre — il connaît la place qu'on lui a donnée. Une carte placée dans une barre latérale de 300 px et la même carte dans une cellule de grille de 900 px ont besoin de mises en page différentes, alors que la largeur de la fenêtre est identique. Les container queries résolvent exactement cela.

Étape 1 : déclarer un contexte de confinement

On interroge un conteneur, il faut donc d'abord marquer un élément comme conteneur avec container-type :

.card-wrapper {
  container-type: inline-size;
}

inline-size signifie « laisse-moi interroger la dimension en ligne (généralement horizontale) » — le choix le plus courant. size interroge les deux dimensions, et normal désactive le confinement.

Étape 2 : l'interroger avec @container

Désormais, tout descendant de .card-wrapper peut s'adapter selon la largeur du wrapper :

.card {
  display: grid;
  gap: 1rem;
}

@container (min-width: 400px) {
  .card {
    grid-template-columns: 150px 1fr;
  }
}

Quand le wrapper fait au moins 400 px de large, la carte passe à une mise en page sur deux colonnes. Placez ce même balisage n'importe où sur la page : il s'adapte à l'endroit où il atterrit — sans aucune media query au niveau de la page.

Un smartphone posé sur une tablette et un portable, trois écrans de tailles différentes
Un même composant doit souvent occuper des espaces très différents. Les container queries lui permettent de s'adapter à son emplacement plutôt qu'à l'appareil.

Nommer les conteneurs

Quand des conteneurs sont imbriqués, nommez-les avec container-name pour qu'une requête vise le bon :

.layout { container: layout / inline-size; } /* nom / type, syntaxe courte */

@container layout (min-width: 600px) {
  .card { /* réagit à .layout, pas à un conteneur plus proche */ }
}

Unités de container query

Les container queries débloquent aussi des unités relatives au conteneur plutôt qu'à la fenêtre : cqw (1 % de la largeur du conteneur), cqh, cqi (en ligne) et cqb (de bloc). Une typographie fluide qui s'adapte à son conteneur tient en une ligne :

.card h2 {
  font-size: clamp(1rem, 5cqi, 2rem);
}

Container queries vs media queries

Media queryContainer query
MesureFenêtre / appareilAncêtre dimensionné le plus proche
PréparationAucunecontainer-type sur un parent
Idéal pourMise en page de la pageComposants réutilisables
Unitésvw, vhcqw, cqi, ...

Support navigateurs

Les container queries de taille sont supportées dans les versions actuelles de Chrome, Edge, Firefox et Safari. Elles ne remplacent pas les media queries — utilisez les media queries pour la structure globale de la page et les container queries pour les composants qui doivent être portables. Les deux fonctionnent bien ensemble.

Le changement de mentalité est petit mais puissant : cessez de demander « quelle est la taille de l'écran ? » et demandez « combien de place ce composant a-t-il ? ». Ce seul changement rend les composants d'un design system vraiment réutilisables partout.