Cascade Layer (die CSS-Regel @layer
) sind in der Betaversion von Chromium 99, Firefox 97 und Safari 15.4 verfügbar. Sie ermöglichen eine explizitere Kontrolle über Ihre CSS-Dateien, um Konflikte bei Stilspezifikationen zu vermeiden. Dies ist besonders nützlich bei großen Codebasen, Designsystemen und bei der Verwaltung von Drittanbieter-Stilen in Anwendungen.
Eine klare Überlagerung Ihres CSS-Codes verhindert unerwartete Stilüberschreibungen und fördert eine bessere CSS-Architektur.
CSS-Spezifität und die Kaskade
Anhand der CSS-Spezifität entscheidet CSS, welche Stile auf welche Elemente angewendet werden. Mit den verschiedenen zur Auswahl stehenden Selektoren wird die Spezifität einer Stilregel bestimmt. Elemente sind beispielsweise weniger spezifisch als Klassen oder Attribute, die wiederum weniger spezifisch sind als IDs. Dies ist ein wesentlicher Bestandteil des CSS-Lernens.
Die Leute verwenden CSS-Namenskonventionen wie BEM, um zu verhindern, dass Spezifitäten versehentlich überschrieben werden. Indem alle Elemente einen einzigen Klassennamen erhalten, befindet sich alles auf derselben Spezifitätsebene. Es ist jedoch nicht immer möglich, solche organisierten Stile beizubehalten, insbesondere wenn Sie mit Code und Designsystemen von Drittanbietern arbeiten.
Dieses Problem soll mit Kaskadenebenen gelöst werden. Sie fügen der CSS-Kaskade eine neue Ebene hinzu. Bei Stilen mit mehreren Ebenen hat eine Ebene immer Vorrang vor der Spezifität eines Selektors.
Der Selektor .post a.link
hat beispielsweise eine höhere Spezifität als .card a
. Wenn Sie versuchen, einen Link zu gestalten, werden Sie innerhalb einer Karte oder eines Beitrags feststellen, dass die spezifischere Auswahl angewendet wird.
Mit @layer
können Sie die Stilspezifität der einzelnen Elemente deutlicher hervorheben und sicherstellen, dass die Stile Ihres Kartenlinks die Stile des Beitrags-Links überschreiben, auch wenn die Spezifität numerisch niedriger sein kann, wenn sich Ihr gesamtes CSS auf derselben Ebene befindet. Dies liegt an der Kaskadenpriorität. Mithilfe von Stilen mit mehreren Ebenen werden neue kaskadierende „Ebenen“ erstellt.
@layer
in Aktion
Dieses Beispiel zeigt die Leistungsfähigkeit von Kaskadenebenen mithilfe von @layer
. Es werden mehrere Links angezeigt: einige ohne zusätzliche Klassennamen, einer mit einer .link
-Klasse und einer mit einer .pink
-Klasse. Der CSS-Code fügt dann drei Ebenen hinzu: base
, typography
und utilities
:
@layer base {
a {
font-weight: 800;
color: red; /* ignored */
}
.link {
color: blue; /* ignored */
}
}
@layer typography {
a {
color: green; /* styles *all* links */
}
}
@layer utilities {
.pink {
color: hotpink; /* styles *all* .pink's */
}
}
Letztendlich sind alle Links entweder grün oder rosa. Das liegt daran: Während .link
eine höhere Spezifität auf Selektorebene hat als a
, gibt es bei a
einen Farbstil in einer @layer
mit höherer Priorität. a { color: green }
überschreibt .link { color: blue }
, wenn sich die grüne Regel auf einer Ebene nach der blauen Regel befindet.
Die Ebene der Ebene ist schneller als die Elementspezifität.
Ebenen organisieren
Sie können Ebenen wie oben gezeigt direkt auf der Seite oder oben in einer Datei organisieren.
Die Ebenenreihenfolge wird festgelegt, indem der jeweilige Ebenenname zum ersten Mal in Ihrem Code erscheint.
Wenn Sie also am Anfang der Datei Folgendes hinzufügen, werden alle Links rot und der Link mit der Klasse .link
blau angezeigt:
@layer utilities, typography, base;
Dies liegt daran, dass die Ebenenreihenfolge jetzt umgekehrt ist, d. h. Dienstprogramme zuerst und Basis am Ende stehen. Daher sind die Stilregeln auf der base
-Ebene immer spezifischer als die Stilregeln in der Typografieebene. Es sind keine grünen Links mehr, sondern rot oder blau.
Importe organisieren
Eine andere Möglichkeit, @layer
zu verwenden, sind Importdateien. Das ist direkt beim Importieren von Stilen möglich. Verwenden Sie dazu eine layer()
-Funktion wie im folgenden Beispiel:
/* Base */
@import '../styles/base/normalize.css' layer(base); /* normalize or rest file */
@import '../styles/base/base.css' layer(base); /* body and base styles */
@import '../styles/base/theme.css' layer(theme); /* theme variables */
@import '../styles/base/typography.css' layer(theme); /* theme typography */
@import '../styles/base/utilities.css' layer(utilities); /* base utilities */
/* Layouts */
@import '../styles/components/post.css' layer(layouts); /* post layout */
/* Components */
@import '../styles/components/cards.css' layer(components); /* imports card */
@import '../styles/components/footer.css' layer(components); /* footer component */
Das obige Code-Snippet hat drei Ebenen: base
, layouts
und components
. Die Normalisierungs-, Design- und Typografiedateien in base
, mit einer post
-Datei in layouts
und cards
und footer
beide in components
. Beim Importieren der Datei werden die Ebenen mithilfe der Funktion „layer“ instanziiert. Ein alternativer Ansatz wäre, Ihre Ebenen am Anfang der Datei zu organisieren und sie vor dem Import zu deklarieren:
@layer base,
theme,
layouts,
components,
utilities;
Die Reihenfolge, in der Sie mit @import
Ihre Stile markieren, spielt für die Ebenenreihenfolge keine Rolle, da sie bereits bei der ersten Instanz des Ebenennamens festgelegt wurde. Darüber müsst ihr euch keine Sorgen machen. Sie können importierte Dateien weiterhin auf bestimmte Ebenen festlegen, die Reihenfolge ist jedoch bereits festgelegt.
Ebenen und die Kaskade
Gehen wir einen Schritt zurück und sehen wir uns an, wo in Bezug auf die größere Kaskade Ebenen verwendet werden:
Die Reihenfolge ist wie folgt:
- User-Agent normal (niedrigste Rangfolge)
- Lokaler Nutzer @layer
- Lokaler Nutzer – normal
- Autor: @layers
- Autor normal
- Autor !wichtig
- Autor @layer !important
- Lokaler Benutzer !wichtig
- User-Agent !important** (höchste Priorität)
Hier sehen Sie möglicherweise, dass @layer !important
-Stile umgekehrt sind. Sie sind nicht weniger spezifisch als Stile ohne Ebenen (normal), sondern haben eine höhere Priorität. Das liegt an der Funktionsweise von !important
in der Kaskade: Es löst die normale Kaskadierung in Ihren Stylesheets auf und kehrt die normale Spezifität auf Ebenenebene (Priorität) um.
Verschachtelte Ebenen
Ebenen können auch in anderen Ebenen verschachtelt sein. Das folgende Beispiel stammt aus der Erklärung zu Kaskadenebenen von Miriam Suzanne:
@layer default {
p { max-width: 70ch; }
}
@layer framework {
@layer default {
p { margin-block: 0.75em; }
}
p { margin-bottom: 1em; }
}
Im obigen Code-Snippet können Sie auf framework.default
zugreifen und dabei eine .
als Signifikanz der default
-Ebene verwenden, die in framework
verschachtelt ist. Sie können dies auch in einem kürzeren Format schreiben:
@layer framework.default {
p { margin-block: 0.75em }
}
Die resultierenden Ebenen und die Reihenfolge der Ebenen sind:
- Standardeinstellung
framework.default
framework
nicht überlagert- Ungeschichtet
Was Sie beachten sollten
Kaskadierende Ebenen können bei korrekter Verwendung eine tolle Sache sein, aber sie können auch zu zusätzlicher Verwirrung und unerwarteten Ergebnissen führen. Achten Sie bei der Arbeit mit Kaskadenebenen auf Folgendes:
Regel 1: @layer
nicht für den Umfang festlegen
Kaskadierende Ebenen lösen keinen Gültigkeitsbereich. Wenn Sie eine CSS-Datei mit einem @layer
haben, sagen Sie card.css
, und Sie möchten alle Links innerhalb der Karte gestalten, schreiben Sie keine Stile wie die folgenden:
a {
…
}
Dies führt dazu, dass alle a
-Tags in Ihrer Datei diese Überschreibung erhalten. Trotzdem ist es wichtig, die Styles richtig anzupassen:
.card a {
…
}
Regel 2: Kaskadierende Ebenen werden hinter CSS ohne Ebenen angeordnet
Dabei ist zu beachten, dass CSS-Dateien ohne Ebenen nicht überschrieben werden. Dies war eine bewusste Entscheidung, um das Einführen von Ebenen auf sinnvollere Weise zu erleichtern, um mit Ihrer vorhandenen Codebasis zu arbeiten. Die Verwendung einer reset.css
-Datei ist beispielsweise ein guter Ausgangspunkt und Anwendungsfall für Kaskadenebenen.
Regel 3: !important
invertiert die Kaskadenspezifität
Während überlagerte Stile im Allgemeinen weniger spezifisch sind als Stile ohne Ebenen, kehren Sie dies mit !important
um. In einer Ebene sind Deklarationen mit der Regel !important
spezifischer als Stile ohne Ebenen.
In diesem Fall kehren die !important
-Stile ihre Spezifität um. Das obige Diagramm zeigt dies als Referenz: author @layers hat eine geringere Priorität als author normal, die wiederum eine geringere Rangfolge als author !important haben, die weniger Vorrang als author @layer !important haben.
Wenn Sie mehrere Ebenen haben, hat die erste Ebene mit !important
die Priorität !important
und ist der spezifischste Stil.
Regel 4: Injektionspunkte verstehen
Da die Ebenenreihenfolge festgelegt wird, wenn ein Ebenenname zum ersten Mal in Ihrem Code erscheint, kann eine @layer
-Deklaration ignoriert werden, nachdem Sie layer()
importiert und festgelegt haben, oder nach einer anderen @layer
-Anweisung. Anders als bei CSS, wo die Stilregel am weitesten unten auf der Seite für Kaskadenebenen angewendet wird, wird die Reihenfolge zuerst festgelegt.
Dies kann in einer Liste, in einem Ebenenblock oder in einem Import erfolgen. Wenn Sie @layer
nach einer Importliste mit layer()
einfügen, geschieht nichts. Wenn Sie es an den Anfang der Datei stellen, wird die Ebenenreihenfolge festgelegt und Sie können die Ebenen innerhalb der Architektur klar erkennen.
Regel 5: Achten Sie auf Ihre Spezifität
Bei Kaskadenebenen überschreibt ein weniger spezifischer Selektor wie a
einen spezifischeren Selektor wie .link
, wenn sich dieser weniger spezifische Selektor auf einer spezifischeren Ebene befindet. Ziehen Sie Folgendes in Betracht:
a
in layer(components)
würde .pink
in layer(utilities)
überschreiben, wenn @layer utilities, components
angegeben wurde. Das ist zwar beabsichtigt, kann aber verwirrend und frustrierend sein, wenn Sie nicht damit rechnen.
Wenn Sie also Dienstprogrammklassen schreiben, fügen Sie diese immer als übergeordnete Ebene ein als die Komponenten, mit denen Sie sie überschreiben möchten. Vielleicht denken Sie: „Ich habe gerade diese .pink
-Klasse hinzugefügt, um die Farbe zu ändern, aber sie wird nicht angewendet.“
Weitere Informationen zu Kaskadenebenen
Sie können sich auch die folgenden Ressourcen ansehen, um mehr über Kaskadenebenen zu erfahren: