Beim Erlernen der Grundprinzipien von CSS lernt man, modulare, wiederverwendbare und beschreibende Stile zu schreiben, um die Wartbarkeit sicherzustellen. Wenn sich Entwickler jedoch mit realen Anwendungen befassen, scheint es oft unmöglich zu sein, UI-Funktionen hinzuzufügen, ohne dass Stile in unbeabsichtigte Bereiche gelangen. Dieses Problem entwickelt sich häufig zu einer sich selbst erfüllenden Schleife. Stile, die theoretisch auf ein Element oder eine Klasse beschränkt sind, werden dort angezeigt, wo sie nicht hingehören. Dies zwingt den Entwickler dazu, noch spezifischere Selektoren zu erstellen, um die durchgesickerten Stile zu überschreiben, die dann versehentlich globale Stile überschreiben, und so weiter. Starre Klassennamenskonventionen wie BEM sind eine theoretische Lösung für dieses Problem. Die BEM-Methodik (Block, Element, Modifier) ist eine systematische Methode zur Benennung von CSS-Klassen, um die Wiederverwendbarkeit und Struktur innerhalb von CSS-Dateien sicherzustellen. Benennungskonventionen wie diese können die kognitive Belastung reduzieren, indem sie die Domänensprache nutzen, um Elemente und ihren Zustand zu beschreiben, und können bei korrekter Implementierung die Pflege von Stilen für große Anwendungen erleichtern. In der realen Welt funktioniert das jedoch nicht immer. Prioritäten können sich ändern und mit der Änderung wird die Umsetzung inkonsistent. Kleine Änderungen an der HTML-Struktur können viele Überarbeitungen des CSS-Klassennamens erfordern. Bei hochgradig interaktiven Front-End-Anwendungen können Klassennamen, die dem BEM-Muster folgen, lang und unhandlich werden (z. B. app-user-overview__status--is-authenticating), und wenn die Benennungsregeln nicht vollständig eingehalten werden, wird die Struktur des Systems zerstört, wodurch seine Vorteile zunichte gemacht werden. Angesichts dieser Herausforderungen ist es kein Wunder, dass Entwickler sich Frameworks zugewandt haben, wobei Tailwind das beliebteste CSS-Framework ist. Anstatt zu versuchen, einen scheinbar nicht gewinnbaren Spezifitätskrieg zwischen Stilen zu bekämpfen, ist es einfacher, die CSS-Kaskade aufzugeben und Tools zu verwenden, die eine vollständige Isolation gewährleisten. Entwickler setzen mehr auf Versorgungsunternehmen Woher wissen wir, dass einige Entwickler kaskadierte Stile unbedingt vermeiden möchten? Es ist der Aufstieg „moderner“ Front-End-Tools – wie CSS-in-JS-Frameworks – die speziell für diesen Zweck entwickelt wurden. Die Arbeit mit isolierten Stilen, die eng auf bestimmte Komponenten beschränkt sind, kann wie ein Hauch frischer Luft wirken. Dadurch entfällt die Notwendigkeit, Dinge zu benennen – immer noch eine der am meisten verhassten und zeitaufwändigsten Front-End-Aufgaben – und ermöglicht es Entwicklern, produktiv zu sein, ohne die Vorteile der CSS-Vererbung vollständig zu verstehen oder zu nutzen. Aber der Verzicht auf die CSS-Kaskade bringt seine eigenen Probleme mit sich. Das Erstellen von Stilen in JavaScript erfordert beispielsweise umfangreiche Build-Konfigurationen und führt häufig dazu, dass Stile unangenehm mit Komponenten-Markup oder HTML vermischt werden. Anstelle sorgfältig durchdachter Namenskonventionen erlauben wir Build-Tools, Selektoren und Identifikatoren automatisch für uns zu generieren (z. B. .jsx-3130221066), was von Entwicklern verlangt, mit einer weiteren Pseudosprache an sich Schritt zu halten. (Als ob die kognitive Belastung, zu verstehen, was alle useEffects Ihrer Komponente bewirken, nicht schon genug wäre!) Eine weitere Abstraktion der Aufgabe der Benennung von Klassen auf Tools bedeutet, dass das grundlegende Debuggen häufig auf bestimmte, für die Entwicklung kompilierte Anwendungsversionen beschränkt ist, anstatt native Browserfunktionen zu nutzen, die Live-Debugging unterstützen, wie z. B. Entwicklertools. Es ist fast so, als müssten wir Tools entwickeln, um die Tools zu debuggen, mit denen wir abstrahieren, was das Web bereits bietet – und das alles, um dem „Schmerz“ des Schreibens von Standard-CSS zu entgehen. Glücklicherweise machen moderne CSS-Funktionen nicht nur das Schreiben von Standard-CSS flexibler, sondern geben Entwicklern wie uns auch viel mehr Möglichkeiten, die Kaskade zu verwalten und sie für uns arbeiten zu lassen. CSS-Kaskadenebenen sind ein gutes Beispiel, aber es gibt noch eine andere Funktion, die überraschend wenig Beachtung findet – obwohl sich das jetzt ändert, da sie kürzlich Baseline-kompatibel ist. Die CSS @scope At-Regel Ich halte die CSS-@scope-at-Regel für ein potenzielles Heilmittel für die von uns behandelte Angst vor Style-Leaks, das uns nicht dazu zwingt, die nativen Webvorteile für Abstraktionen und zusätzliche Build-Tools zu gefährden. „Mit der @scope-CSS-at-Regel können Sie Elemente in bestimmten DOM-Unterbäumen auswählen und gezielt auf Elemente abzielen, ohne übermäßig spezifische Selektoren zu schreiben, die schwer zu überschreiben sind, und ohne Ihre Selektoren zu eng an die DOM-Struktur zu koppeln.“ – MDN
Mit anderen Worten: Wir können in bestimmten Fällen mit isolierten Stilen arbeiten, ohne auf Vererbung, Kaskadierung oder sogar die grundlegende Trennung von Belangen zu verzichtenDas ist seit langem ein Leitprinzip der Frontend-Entwicklung. Außerdem verfügt es über eine hervorragende Browserabdeckung. Tatsächlich hat Firefox 146 im Dezember Unterstützung für @scope hinzugefügt und es damit erstmals Baseline-kompatibel gemacht. Hier ist ein einfacher Vergleich zwischen einer Schaltfläche, die das BEM-Muster verwendet, und der @scope-Regel:
Die @scope-Regel ermöglicht Präzision bei geringerer Komplexität. Der Entwickler muss keine Grenzen mehr mithilfe von Klassennamen erstellen, was ihm wiederum ermöglicht, Selektoren auf Basis nativer HTML-Elemente zu schreiben, wodurch die Notwendigkeit vorschreibender CSS-Klassennamenmuster entfällt. Durch den einfachen Wegfall der Notwendigkeit einer Klassennamenverwaltung kann @scope die mit CSS in großen Projekten verbundenen Ängste lindern.
Grundlegende Verwendung
Fügen Sie zunächst die @scope-Regel zu Ihrem CSS hinzu und fügen Sie einen Root-Selektor ein, für den die Stile gelten:
@scope (
Wenn wir beispielsweise Stile auf ein
@scope (nav) { a { /* Link-Stile im Navigationsbereich */ }
a:active { /* Aktive Link-Stile */ }
a:active::before { /* Aktiver Link mit Pseudoelement für zusätzliches Styling */ }
@media (maximale Breite: 768 Pixel) { a { /* Responsive Anpassungen */ } } }
Dies allein ist kein bahnbrechendes Merkmal. Allerdings kann dem Bereich ein zweites Argument hinzugefügt werden, um eine untere Grenze zu erstellen, die effektiv die Start- und Endpunkte des Bereichs definiert.
/* Auf jedes a-Element in ul werden die Stile nicht angewendet */ @scope (nav) zu (ul) { ein { Schriftgröße: 14px; } }
Diese Vorgehensweise wird Donut-Scoping genannt, und es gibt mehrere Ansätze, die man verwenden könnte, einschließlich einer Reihe ähnlicher, hochspezifischer Selektoren, die eng an die DOM-Struktur gekoppelt sind, eines :not-Pseudoselektors oder der Zuweisung spezifischer Klassennamen zu -Elementen innerhalb von