// css · Web Platform Advent #7
Imbrication CSS native : le sélecteur &, le support navigateurs et les différences avec Sass
Écrire du CSS imbriqué sans préprocesseur. Fonctionnement du sélecteur d'imbrication &, différences avec Sass et navigateurs qui le supportent aujourd'hui.
L'imbrication CSS permet d'écrire des règles à l'intérieur d'autres règles, pour garder ensemble les styles qui vont ensemble. Pendant des années, ce n'était possible qu'avec un préprocesseur comme Sass. C'est désormais une fonctionnalité native du CSS, présente dans tous les navigateurs modernes — sans étape de compilation.
L'idée de base
Au lieu de répéter le sélecteur parent pour chaque enfant, on imbrique la règle enfant à l'intérieur. Ces deux blocs produisent le même résultat :
/* CSS plat, traditionnel */
.card { padding: 1rem; }
.card h2 { margin: 0; }
.card p { color: #555; }
/* Imbriqué */
.card {
padding: 1rem;
h2 { margin: 0; }
p { color: #555; }
} Chaque sélecteur imbriqué est lu relativement à son parent : c'est bien .card p que le navigateur applique au final.
Le sélecteur d'imbrication &
L'esperluette & désigne le sélecteur parent. Elle est nécessaire dès que le sélecteur imbriqué doit s'attacher directement au parent plutôt que décrire un descendant — pseudo-classes, classes modificatrices et sélecteurs composés :
.btn {
background: #2563eb;
&:hover { background: #1d4ed8; } /* .btn:hover */
&.is-active { background: #1e40af; } /* .btn.is-active */
} Sans le &, un simple :hover serait traité comme un descendant : .btn *:hover, ce qui n'est presque jamais l'effet voulu. Quand un sélecteur imbriqué commence par un élément ou une classe (comme p ci-dessus), le navigateur insère pour vous un combinateur de descendance implicite.
Imbriquer les media queries
On peut imbriquer @media (et d'autres at-rules) dans un sélecteur, gardant les ajustements responsive à côté de la règle qu'ils modifient :
.sidebar {
width: 100%;
@media (min-width: 768px) {
width: 280px;
}
} Différences avec Sass
La syntaxe ressemble à Sass, mais les deux ne sont pas identiques. Les différences qui surprennent le plus :
- Concaténation : Sass permet de construire des sélecteurs comme
&__title(BEM). L'imbrication native CSS ne concatène pas —&__titleest invalide. Il faut écrire le nom de classe complet. - Pas de compilation : l'imbrication native s'exécute dans le navigateur, donc rien à compiler et pas de source maps à gérer.
- Spécificité de & : en CSS natif,
&se comporte comme:is()et prend la spécificité du sélecteur le plus spécifique de la liste parente, ce qui peut différer subtilement de la sortie Sass.
Support navigateurs et solution de repli
L'imbrication CSS native est supportée dans les versions actuelles de Chrome, Edge, Firefox et Safari. Les premières implémentations exigeaient que le sélecteur imbriqué commence par un symbole (on écrivait & p au lieu de p) ; la syntaxe assouplie autorisant un sélecteur d'élément nu est celle des navigateurs actuels. Si vous devez supporter des moteurs plus anciens, continuez avec Sass ou PostCSS — le plugin postcss-nesting compile l'imbrication native en CSS plat.
Aide-mémoire
| Vous voulez | Écrivez |
|---|---|
| Descendant | .card { p { ... } } |
| Pseudo-classe | &:hover { ... } |
| Classe modificatrice | &.is-active { ... } |
| Responsive | @media (...) { ... } imbriqué |
| Concaténation BEM | non supportée — écrire la classe complète |
L'imbrication native supprime l'une des dernières grandes raisons de recourir à un préprocesseur sur un nouveau projet. Gardez l'imbrication peu profonde — deux ou trois niveaux — et vos feuilles de style restent lisibles tout en rendant évidentes les relations entre sélecteurs.