Le `@scope` CSS est là : sortir des classes utilitaires sans recréer une usine à gaz
Adoptez @scope CSS pour isoler les styles de composants, réduire les conventions de classes et garder une cascade lisible et maintenable.
@scope réduit les collisions sans alourdir les sélecteurs
@scope permet de limiter les styles à la zone d’un composant sans préfixer chaque sélecteur par de longues classes. Utilisez-le pour des composants dont la racine DOM est claire et dont les styles ne doivent pas déborder ailleurs.
Il ne remplace pas toutes les conventions de nommage. Les classes restent utiles pour les variantes, les états et les contrats publics entre composants, notamment lorsque la structure interne est ambiguë ou changeante.
Ce que la règle change dans la cascade
Les conventions de classes évitent une cascade incontrôlée, mais peuvent charger le HTML de classes de structure, de variation et d’espacement. À l’inverse, des sélecteurs globaux sur h2, a ou footer peuvent toucher involontairement des éléments ajoutés plus tard.
Avec @scope, une racine délimite le sous-arbre auquel s’appliquent les règles du bloc. Le sélecteur de racine n’est pas ajouté à chaque règle : un h2 interne ne cible que les titres dans cette portée.
@scope (.card) {
:scope { border: 1px solid #d9d9d9; border-radius: 0.75rem; }
h2 { margin: 0; font-size: 1.25rem; }
a { color: #0759c7; }
}
La spécificité des sélecteurs ne change pas : h2 garde la spécificité d’un sélecteur de type. À spécificité égale, la cascade tient aussi compte de la proximité de la portée ; testez donc les composants imbriqués lorsque plusieurs portées ciblent le même élément.
Structurer un composant localement
Une carte peut ne garder qu’une classe sur sa racine et cibler les éléments HTML de sa structure interne. Cette approche reste lisible tant que chaque élément a un rôle unique ; plusieurs titres ou liens distincts demandent plutôt une classe ou un attribut explicite.
<article class="card">
<img src="/image.webp" alt="Aperçu de l’article">
<h2>Réduire le JavaScript inutile</h2>
<p>Des choix concrets pour un front plus simple.</p>
<footer><a href="/article">Lire l’article</a></footer>
</article>
@scope (.card) to (.card) {
:scope { display: grid; gap: 1rem; padding: 1rem; }
img { width: 100%; height: auto; border-radius: 0.5rem; }
h2 { margin: 0; }
p { margin: 0; color: #4b5563; }
footer { display: flex; justify-content: flex-end; }
}
La limite to (.card) empêche les règles d’une carte parente de traverser une carte imbriquée. Elle est utile lorsque les composants de même type peuvent se contenir.
Limites et adoption progressive
Gardez hors des portées les tokens CSS, les styles de base, la typographie globale et les thèmes. @scope n’offre pas une isolation complète comme le Shadow DOM : des règles globales peuvent encore viser les éléments internes et les propriétés héritées continuent de circuler.
Évitez de vous y fier seul pour un élément rendu hors de son composant dans le DOM, comme une fenêtre modale dans un portail. Surveillez aussi les personnalisations de composants imbriqués et les variables CSS héritées.
Les navigateurs qui ne reconnaissent pas @scope ignorent son bloc. Vérifiez vos navigateurs cibles dans la documentation MDN de @scope, testez les parcours réels et prévoyez, si nécessaire, un CSS de repli avec des sélecteurs préfixés par la racine du composant.
Introduisez d’abord la règle sur de nouveaux composants ou lors d’une refonte locale, en conservant les sélecteurs existants pour les zones critiques. Choisissez un composant dont la structure est stable et évaluez si la feuille de style devient réellement plus lisible.