Maison >interface Web >tutoriel CSS >Résolu par CSS: Donuts Scopes
Imaginez que vous avez un composant Web qui peut afficher beaucoup de contenu différent. Il aura probablement une fente quelque part où d'autres composants peuvent être injectés. Le composant parent a également ses propres styles sans rapport avec les styles des composants de contenu qu'il peut contenir.
Cela fait une situation difficile: Comment pouvons-nous empêcher les styles de composants parents de fuir vers l'intérieur?
Ce n'est pas un nouveau problème - Nicole Sullivan l'a décrit en 2011! Le principal problème est d'écrire CSS afin qu'il n'affecte pas le contenu, et elle l'a inventé avec précision comme Donut Scoping .
«Nous avons besoin d'un moyen de dire, non seulement où la portée commence, mais là où elle se termine. Ainsi, la portée du beignet ».
Même si la portée des beignets est un problème ancien en années Web, si vous effectuez une recherche rapide sur la «portée des beignets CSS» dans votre moteur de recherche de choix, vous remarquerez peut-être deux choses:
Nous obtenons des résultats similaires même avec une requête intelligente "CSS Donut Scope - @ Scope", et aller année par année ne semble pas apporter quelque chose de nouveau au tableau Donut Scope . Il semble que Donut Scopes soit resté à l'arrière de nos esprits comme un autre mal de tête de la portée globale de l'Ol 'CSS jusqu'à @Scope.
et (spoiler!), Bien que le @scope at-rule apporte un chemin plus facile pour la portée des beignets, je pense qu'il doit y avoir plus de tentatives de solutions au fil des ans. Nous nous aventurerons à travers chacun d'eux, en faisant un dernier arrêt à la solution d'aujourd'hui, @Scope. C'est un bel exercice dans l'histoire du CSS!
Prenez, par exemple, l'écran de jeu suivant. Nous avons un élément .parent avec un ensemble d'onglet et un emplacement .Content, dans lequel un composant. Si nous changeons la couleur.
Comment pouvons-nous empêcher que cela se produise? Je veux empêcher le texte à l'intérieur de .Content de hériter de la couleur du parent.Il suffit de l'ignorer!
La première solution n'est pas du tout une solution! C'est peut-être l'approche la plus utilisée car la plupart des développeurs peuvent vivre leur vie sans les joies de la portée des beignets (fou, non?). Soyons plus tangibles ici, il ne l'ignore pas simplement, mais plutôt accepter les styles mondiaux de portée et d'écriture de CSS avec cet esprit. De retour à notre premier exemple, nous supposons que nous ne pouvons pas empêcher les styles des parents de fuir vers l'intérieur vers le composant de contenu, nous écrivons donc les styles de nos parents avec moins de spécificité, afin qu'ils puissent être remplacés par les styles de contenu.
body { color: blue; } .parent { color: orange; /* Initial background */ } .content { color: blue; /* Overrides parent's background */ }
Bien que cette approche soit suffisante pour l'instant, gérer les styles uniquement par leur spécificité en tant que projet devient plus élargi devient fastidieux, au mieux, et au pire chaotique. Les composants peuvent se comporter différemment selon l'endroit où ils sont fendus et changer notre CSS ou HTML peut briser d'autres styles de manière inattendue.
Deux propriétés CSS entrent dans un bar. Un tabouret de bar dans un bar complètement différent tombe.
Thomas Fuchs
Vous pouvez voir comment, dans ce petit exemple, nous devons remplacer deux fois les styles:
Notre objectif, alors il s'agit de ne faire que de la mise en place du .Parent, laissant de côté tout ce qui peut être inséré dans la fente. Donc, pas le continent mais le reste de .parent… pas le .Content… : pas ()! Nous pouvons utiliser le sélecteur: non () pour ne pas étendre les descendants directs de .parent qui ne sont pas .Content.
body { color: blue; } .parent > :not(.content) { color: orange; }
De cette façon, les styles .Content ne seront pas dérangés par les styles définis dans leur .parent:
Vous pouvez voir une immense différence lorsque nous ouvrons les Devtools pour chaque exemple:
Aussi bon qu'une amélioration, le dernier exemple a une portée superficielle. Donc, s'il y avait une autre fente imbriquée plus profondément, nous ne pourrions pas l'atteindre à moins que nous sachions à l'avance où il va être placé.
C'est parce que nous utilisons le sélecteur descendant direct (& gt;), mais je n'ai pas pu trouver de moyen de le faire fonctionner sans lui. Même en utilisant une combinaison de sélecteurs complexes à l'intérieur: pas () ne semble pas mener n'importe où utile. Par exemple, en 2021, le Dr Lea Verou a mentionné la portée du beignet avec: non () en utilisant le cocktail sélecteur suivant:
.container:not(.content *) { /* Donut Scoped styles (?) */ }
Cependant, cet extrait semble correspondre à la classe .Container / .parent au lieu de ses descendants, et il est à noter qu'il serait toujours superficiel de scoping de beignet:
jusqu'à ce que tous les navigateurs modernes prennent désormais en charge les sélecteurs complexes: pas ()! ?
Test: https://t.co/rhsjardvsw
(@Leaverou) 28 janvier 2021
Donut Scoping avec @scope
Quoi de mieux, nous pouvons laisser des emplacements à l'intérieur du sous-arbre que nous avons sélectionnés (généralement appelé la racine de portée). Dans ce cas, nous voudrions styliser l'élément.
body { color: blue; } .parent { color: orange; /* Initial background */ } .content { color: blue; /* Overrides parent's background */ }
Et quoi de mieux, il détecte chaque élément de contenu à l'intérieur .parent, peu importe à quel point il peut être imbriqué. Nous n'avons donc pas à nous soucier de l'endroit où nous écrivons nos créneaux. Dans le dernier exemple, nous pourrions à la place écrire le style suivant pour modifier la couleur du texte de l'élément dans .parent sans toucher .Content:
body { color: blue; } .parent > :not(.content) { color: orange; }
Bien qu'il puisse sembler gênant de répertorier tous les éléments que nous allons changer, nous ne pouvons pas utiliser quelque chose comme le sélecteur universel (*) car il gâcherait la portée des Sintes imbriquées. Dans cet exemple, il laisserait le contenu imbriqué hors de portée, mais pas son conteneur. Étant donné que la propriété de couleur hérite, le contenu imbriqué changerait les couleurs malgré tout!
et voilà! Les deux emplacements de continent sont à l'intérieur de nos trous de beignets dans les lunettes:
La portée peu profonde est toujours possible avec cette méthode, nous devons simplement réécrire notre sélecteur de machines à sous afin que seuls les descendants de contente directs de .Parent sont exclus de la portée. Cependant, nous devons utiliser le: sélecteur de portée, qui fait référence à la racine de cadrage, ou .parent dans ce cas:
.container:not(.content *) { /* Donut Scoped styles (?) */ }
Nous pouvons utiliser le sélecteur universel dans ce cas car il est peu profond.
Donut Scoping, une caractéristique en herbe inventée en 2011 a finalement été animée en 2024. Il est toujours déroutant de la façon dont il semblait rester dans le fond de nos esprits jusqu'à récemment, comme une simple conséquence de la portée mondiale du CSS, alors qu'elle avait tant de bizarreries en elle-même. Il serait cependant injuste de dire qu'il est passé sous les radars de tout le monde, car le CSSWG (les personnes derrière la rédaction de la spécification des nouvelles fonctionnalités CSS) avait clairement l'intention de s'adresser lors de la rédaction de la spécification pour le @Scope at-Rule.
Quoi qu'il en soit, je suis reconnaissant que nous puissions avoir une véritable portée de beignet dans notre CSS. Dans une certaine mesure, nous devons encore attendre que Firefox le soutient. ?
Ces données de support du navigateur proviennent de Caniuse, qui a plus de détails. Un nombre indique que le navigateur prend en charge la fonctionnalité de cette version et plus.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!