L'une de nos fonctionnalités préférées de préprocesseur CSS est désormais intégrée au langage: l'imbrication des règles de style.
Avant l'imbrication, chaque sélecteur devait être explicitement déclaré, séparément des les uns les autres. Cela entraîne des répétitions, l'encombrement de la feuille de style et une création éparse expérience.
.nesting { color: hotpink; } .nesting > .is { color: rebeccapurple; } .nesting > .is > .awesome { color: deeppink; }
Après l'imbrication, les sélecteurs peuvent être les règles de style continu et associées peuvent être regroupées.
.nesting { color: hotpink; > .is { color: rebeccapurple; > .awesome { color: deeppink; } } }
Essayez dans votre navigateur.
L'imbrication aide les développeurs en leur évitant d'avoir à répéter les sélecteurs tout en réduisant
règles de style de colocalisation des éléments associés. Cela peut également aider les styles à correspondre
HTML ciblé. Si le composant .nesting
de l'exemple précédent était
du projet, vous pouvez supprimer l'ensemble du groupe au lieu de rechercher
pour les instances de sélecteur associées.
L'imbrication peut vous aider à: - Organisation - Réduction de la taille de fichier - Refactorisation
L'imbrication est disponible à partir de Chrome 112 et peut également être essayée dans la version preview technique de Safari 162.
Premiers pas avec l'imbrication CSS
Dans la suite de cet article,le bac à sable de démonstration suivant sera utilisé pour vous aider visualiser les sélections. Dans cet état par défaut, rien n'est sélectionné et que tout est visible. En sélectionnant les différentes formes et tailles, vous pouvez pratiquer la syntaxe et la voir en action.
À l'intérieur du bac à sable se trouvent des cercles, des triangles et des carrés. Certaines sont petites ou moyennes
ou de grande taille. D'autres sont bleus, roses ou violets. Ils se trouvent tous dans le .demo
l'élément conteneur. Voici un aperçu des éléments HTML qui vous seront
le ciblage.
<div class="demo">
<div class="sm triangle pink"></div>
<div class="sm triangle blue"></div>
<div class="square blue"></div>
<div class="sm square pink"></div>
<div class="sm square blue"></div>
<div class="circle pink"></div>
…
</div>
Exemples d'imbrication
L'imbrication CSS vous permet de définir des styles pour un élément dans le contexte de un autre sélecteur.
.parent {
color: blue;
.child {
color: red;
}
}
Dans cet exemple, le sélecteur de classe .child
est imbriqué dans
le sélecteur de classe .parent
. Cela signifie que le sélecteur .child
imbriqué
ne s'appliquent qu'aux éléments enfants d'éléments ayant une classe .parent
.
Cet exemple peut également être écrit à l'aide du symbole &
, pour indiquer explicitement
indiquent où la classe parente doit être placée.
.parent {
color: blue;
& .child {
color: red;
}
}
Ces deux exemples sont fonctionnellement équivalents et la raison pour laquelle vous disposez de plusieurs options deviendra plus clair au fur et à mesure que nous examinerons des exemples plus avancés.
Sélection des cercles
Pour ce premier exemple, la tâche consiste à ajouter des styles pour fondre et flouter uniquement cercles dans la démo.
Aujourd'hui, sans imbrication, les CSS:
.demo .circle {
opacity: .25;
filter: blur(25px);
}
Avec l'imbrication, il existe deux façons valides:
/* & is explicitly placed in front of .circle */
.demo {
& .circle {
opacity: .25;
filter: blur(25px);
}
}
ou
/* & + " " space is added for you */
.demo {
.circle {
opacity: .25;
filter: blur(25px);
}
}
Le résultat : tous les éléments dans .demo
avec une classe .circle
sont
floutées et presque invisibles:
Sélectionner des triangles et des carrés
Cette tâche nécessite de sélectionner plusieurs éléments imbriqués, également appelés sélecteurs de groupe.
Aujourd'hui, sans imbrication, il existe deux façons d'utiliser le CSS:
.demo .triangle,
.demo .square {
opacity: .25;
filter: blur(25px);
}
ou, à l'aide de :is()
/* grouped with :is() */
.demo :is(.triangle, .square) {
opacity: .25;
filter: blur(25px);
}
Avec l'imbrication, voici deux méthodes valables:
.demo {
& .triangle,
& .square {
opacity: .25;
filter: blur(25px);
}
}
ou
.demo {
.triangle, .square {
opacity: .25;
filter: blur(25px);
}
}
Résultat : il ne reste que des éléments .circle
dans .demo
:
Sélectionner de grands triangles et cercles
Cette tâche nécessite un sélecteur composé, où les deux classes doivent être présentes pour que les éléments soient sélectionnés.
Aujourd'hui, sans imbrication, les CSS:
.demo .lg.triangle,
.demo .lg.square {
opacity: .25;
filter: blur(25px);
}
ou
.demo .lg:is(.triangle, .circle) {
opacity: .25;
filter: blur(25px);
}
Avec l'imbrication, voici deux méthodes valables:
.demo {
.lg.triangle,
.lg.circle {
opacity: .25;
filter: blur(25px);
}
}
ou
.demo {
.lg {
&.triangle,
&.circle {
opacity: .25;
filter: blur(25px);
}
}
}
Résultat, tous les grands triangles et cercles sont masqués dans .demo
:
Conseil de pro avec les sélecteurs composés et l'imbrication
Le symbole &
est votre ami ici, car il montre explicitement comment joindre des
sélecteurs. Prenons l'exemple suivant :
.demo {
.lg {
.triangle,
.circle {
opacity: .25;
filter: blur(25px);
}
}
}
Bien qu'il s'agisse d'une méthode d'imbrication valide, les résultats ne correspondront pas aux éléments attendus.
En effet, sans &
pour spécifier le résultat souhaité de la combinaison de .lg.triangle,
.lg.circle
, le résultat réel serait .lg .triangle, .lg
.circle
. sélecteurs descendants.
Sélection de toutes les formes sauf celles roses
Cette tâche nécessite une pseudo-classe fonctionnelle de négation, dans laquelle les éléments ne doivent pas sont associés au sélecteur spécifié.
Aujourd'hui, sans imbrication, les CSS:
.demo :not(.pink) {
opacity: .25;
filter: blur(25px);
}
Avec l'imbrication, voici deux méthodes valables:
.demo {
:not(.pink) {
opacity: .25;
filter: blur(25px);
}
}
ou
.demo {
& :not(.pink) {
opacity: .25;
filter: blur(25px);
}
}
Résultat : toutes les formes qui ne sont pas roses sont masquées dans .demo
:
Précision et flexibilité avec &
Imaginons que vous vouliez cibler .demo
avec le sélecteur :not()
. &
est obligatoire pour
que:
.demo {
&:not() {
...
}
}
Elle combine .demo
et :not()
en .demo:not()
, par opposition à l'appellation précédente
qui nécessitait .demo :not()
. Ce rappel est très important
lorsque
qui souhaitent imbriquer une interaction :hover
.
.demo {
&:hover {
/* .demo:hover */
}
:hover {
/* .demo :hover */
}
}
Autres exemples d'imbrication
La spécification CSS pour l'imbrication est rempli d’autres exemples. Si vous souhaitez en savoir plus sur la syntaxe à travers des exemples, il couvre un large éventail d'exemples valides et non valides.
Les exemples suivants présentent brièvement une fonctionnalité d'imbrication CSS pour vous aider comprendre l'étendue des fonctionnalités qu'il introduit.
Imbriquer @media
Il peut être très gênant de passer à une autre partie de la feuille de style les conditions de requête média qui modifient un sélecteur et ses styles. Cette distraction a disparu avec la possibilité d'imbriquer les conditions directement dans le contexte.
Pour des raisons de syntaxe, si la requête média imbriquée ne modifie que les styles pour le contexte de sélecteur actuel, une syntaxe minimale peut être utilisée.
.card {
font-size: 1rem;
@media (width >= 1024px) {
font-size: 1.25rem;
}
}
Vous pouvez également utiliser explicitement &
:
.card {
font-size: 1rem;
@media (width >= 1024px) {
&.large {
font-size: 1.25rem;
}
}
}
Cet exemple présente la syntaxe étendue avec &
, tout en ciblant .large
pour montrer que d'autres fonctionnalités d'imbrication continuent de fonctionner.
En savoir plus sur l'imbrication de @rules
Nest Protect n'importe où
Tous les exemples jusqu'à présent se sont poursuivis ou sont ajoutés à un contexte précédent. Vous pouvez complètement modifier ou réorganiser le contexte si nécessaire.
.card {
.featured & {
/* .featured .card */
}
}
Le symbole &
représente une référence à un objet sélecteur (et non à une chaîne).
peut être placé n'importe où dans un sélecteur imbriqué. Il peut même être placé
fois:
.card {
.featured & & & {
/* .featured .card .card .card */
}
}
Bien que cet exemple semble peu utile, il y a certainement des cas où pouvoir répéter un contexte de sélecteur est pratique.
Exemples d'imbrication non valides
Certains scénarios de syntaxe d'imbrication sont incorrects et peuvent vous surprendre si vous avez imbriqué dans des préprocesseurs.
Imbriquer et concaténation
De nombreuses conventions de nommage de classe CSS comptent sur la capacité de l'imbrication à concaténer ou ajouter des sélecteurs comme s'il s'agissait de chaînes. Cela ne fonctionne pas dans l'imbrication CSS, car les sélecteurs ne sont pas des chaînes, ce sont des références d'objets.
.card {
&--header {
/* is not equal to ".card--header" */
}
}
Pour en savoir plus, consultez les spécifications.
Exemple d'imbrication complexe
Imbriquer des listes de sélecteurs et :is()
Prenons l'exemple du bloc CSS d'imbrication suivant:
.one, #two {
.three {
/* some styles */
}
}
Il s'agit du premier exemple qui commence par une liste de sélecteurs, puis qui continue à s'imbriquer. Les exemples précédents se terminaient seulement par une liste de sélecteurs. Cet exemple d'imbrication n'a rien de non valide, mais il existe un détail d'implémentation potentiellement délicat concernant l'imbrication dans des listes de sélecteurs, en particulier celles qui incluent un sélecteur d'ID.
Pour que l'intent de l'imbrication fonctionne, toute liste de sélecteur qui n'est pas la plus imbriquée interne sera encapsulée avec :is()
par le navigateur. Cette encapsulation permet de conserver le regroupement de la liste de sélecteur dans tous les contextes créés. L'effet secondaire de ce regroupement, :is(.one, #two)
, est qu'il adopte la spécificité du score le plus élevé dans les sélecteurs entre parenthèses. C'est toujours ainsi que :is()
fonctionne, mais l'utilisation de la syntaxe d'imbrication peut être surprenante, car ce n'est pas exactement ce qui a été créé. L'astuce est résumée ; l'imbrication avec des ID et des listes de sélecteurs peut générer des sélecteurs de spécificité très élevés.
Pour récapituler clairement l'exemple délicat, le bloc d'imbrication précédent sera appliqué au document comme suit:
:is(.one, #two) .three {
/* some styles */
}
Restez à l'affût ou apprenez à vos lints à vous avertir lorsque l'imbrication dans une liste de sélecteur utilise un sélecteur d'ID, la spécificité de toutes les imbrications dans cette liste de sélecteur sera élevée.
Combiner l'imbrication et les déclarations
Prenons l'exemple du bloc CSS d'imbrication suivant:
.card {
color: green;
& { color: blue; }
color: red;
}
Les éléments .card
seront de couleur blue
.
Toutes les déclarations de style mélangées sont hissées en haut, comme si elles étaient créées avant toute imbrication. Pour en savoir plus, consultez les spécifications.
Il existe des solutions. Le code suivant encapsule les trois styles de couleur dans &
, qui
maintient l'ordre de la cascade comme
l'auteur peut l'avoir prévu. La couleur du
.card
éléments seront rouges.
.card {
color: green;
& { color: blue; }
& { color: red; }
}
En fait, il est recommandé d'encapsuler tous les styles qui suivent l'imbrication avec un &
.
.card {
color: green;
@media (prefers-color-scheme: dark) {
color: lightgreen;
}
& {
aspect-ratio: 4/3;
}
}
Détection de caractéristiques
Il existe deux méthodes efficaces pour détecter l'imbrication CSS: utiliser l'imbrication ou utiliser
@supports
pour vérifier la capacité d'analyse du sélecteur d'imbrication.
En utilisant l'imbrication:
html {
.has-nesting {
display: block;
}
.no-nesting {
display: none;
}
}
En utilisant @supports
:
@supports (selector(&)) {
/* nesting parsing available */
}
Mon collègue Bramus utilise un excellent Codepen pour illustrer cette stratégie.
Débogage avec les outils pour les développeurs Chrome
L'imbrication est actuellement très peu prise en charge dans les outils de développement. Actuellement, vous trouverez styles sont représentés dans le volet "Styles" comme prévu, mais le traçage de l'imbrication et son contexte de sélecteur complet n'est pas encore pris en charge. Nous avons conçu et prévu à rendre cela transparent et clair.
Chrome 113 prévoit une prise en charge supplémentaire de l'imbrication CSS. N'hésitez pas à vous tenir informé.
L'avenir
L'imbrication CSS est disponible dans la version 1 uniquement. La version 2 introduira davantage de sucre syntaxique et potentiellement moins de règles pour mémoriser. L'analyse de l'imbrication est très demandée pour ne pas limiter ou qui ont des moments difficiles.
L'imbrication améliore considérablement le langage CSS. Il a des implications de création à presque tous les aspects architecturaux du CSS. Cet impact majeur doit être profondément exploré et compris avant de pouvoir spécifier la version 2.
Pour conclure, voici une démonstration
qui utilise @scope
, l'imbrication et @layer
ensemble. C'est très excitant !