Eine neue Sache kommt in CSS: @layer.
Das kommt von Miriam Suzanne, die wirklich auf einer Welle ist, wichtige neue CSS-Sachen zu beeinflussen. Ich habe all das gehört, und dann ist es plötzlich in experimentellen Browsern erschienen.
Bramus hat sich das alles genau angesehen mit einem fantastischen Beitrag dazu.
Mit der Einführung von Cascade Layers werden wir Entwickler mehr Werkzeuge zur Verfügung haben, um die Kaskade zu kontrollieren. Die wahre Stärke von Cascade Layers liegt in ihrer einzigartigen Position in der Kaskade: vor der Selektorspezifität und der Reihenfolge des Erscheinens. Deshalb müssen wir uns keine Gedanken über die Selektorspezifität des CSS machen, das in anderen Layern verwendet wird, noch über die Reihenfolge, in der wir CSS in diese Layer laden – etwas, das für größere Teams oder beim Laden von Drittanbieter-CSS sehr nützlich sein wird.
Bramus Van Damme, „Die Zukunft von CSS: Cascade Layers (CSS@layer)“
Hervorhebung von mir.
Das ist der Kernpunkt: Dies ist eine neue Sache, die beeinflusst, welche Selektoren gewinnen. Es wird einige Umstrukturierungen unserer CSS-Denkweise erfordern, da Layer ein völlig neuer (und mächtiger) Teil der Bestimmung dessen sind, welche Stile tatsächlich angewendet werden.

Ich sage mächtig, weil ein „höherer“ Layer buchstäblich einen traditionell stärkeren Selektor schlagen kann, selbst mit einem schwächeren Selektor im Layer.
/* First layer */
@layer base-layer {
body#foo {
background: tan;
}
}
/* Higher layer, so this wins, despite selector strength */
@layer theme-layer {
body.foo {
background: #eee;
}
}
/* Careful! Unlayered styles are more powerful than layers, even if the selector is weaker */
body {
background: red;
}
Da das CSS unten nicht in einem Layer ist, gewinnt es, auch mit dem schwächeren Selektor.
Und Sie sind nicht auf einen Layer beschränkt. Sie können sie definieren und so verwenden, wie Sie möchten.
@layer reset; /* Create 1st layer named “reset” */
@layer base; /* Create 2nd layer named “base” */
@layer theme; /* Create 3rd layer named “theme” */
@layer utilities; /* Create 4th layer named “utilities” */
/* Or, @layer reset, base, theme, utilities; */
@layer reset { /* Append to layer named “reset” */
/* ... */
}
@layer theme { /* Append to layer named “theme” */
/* ... */
}
@layer base { /* Append to layer named “base” */
/* ... */
}
@layer theme { /* Append to layer named “theme” */
/* ... */
}
Wirklich atemberaubend.
Wie werden wir das nutzen?
Ich frage mich, ob ein gängiges Muster entstehen könnte…
- Layer *alles*, damit die Prioritätsstufen wirklich klar sind. *Vielleicht* unlayered CSS für nur sehr mächtige Überschreibungen zulassen, aber idealerweise auch das als High-Level-Layer.
- Resets als unterster Layer.
- Drittanbieter-Sachen als mittlerer/mittlere Layer.
- Alles, was vom Team erstellt wurde, als höchster Layer.
Sie müssen sich keine Gedanken machen, Platz dazwischen zu lassen (wie Sie es vielleicht mit z-index tun), da Sie ihn anpassen können, ohne jederzeit Zahlen anhängen zu müssen.
Die Zeit wird es zeigen.
Debugging
Ich hoffe, DevTools wird Layer sehr klar darstellen, denn es wird eine Weile lang ernsthaftes Kopfzerbrechen geben, wenn wir schwächer aussehende Selektoren sehen, die wegen der Layer-Platzierung gewinnen.
Browser-Unterstützung
Sieht so aus, als wäre caniuse hier am Ball!
Diese Browser-Support-Daten stammen von Caniuse, die mehr Details haben. Eine Zahl bedeutet, dass der Browser die Funktion ab dieser Version und aufwärts unterstützt.
Desktop
| Chrome | Firefox | IE | Edge | Safari |
|---|---|---|---|---|
| 99 | 97 | Nein | 99 | 15.4 |
Mobil / Tablet
| Android Chrome | Android Firefox | Android | iOS Safari |
|---|---|---|---|
| 127 | 127 | 127 | 15.4 |
Aktualisierungen
Diese Sachen sind brandneu (zum Zeitpunkt des Schreibens), daher ist Volatilität zu erwarten, nehme ich an. Es sieht so aus, als ob am 6. Oktober 2021 beschlossen wurde, dass *un*layered Styles tatsächlich die stärksten Styles sind, nicht die schwächsten. Ich habe versucht, den Artikel zu aktualisieren, um das zu zeigen.
Ich will nicht unhöflich sein, aber ich sehe buchstäblich keinen Nutzen darin.
Kann mir jemand ein plausibles Beispiel geben?
Vielen Dank!
Es wird nützlich sein, bestehende Stile zu überschreiben. Sagen wir, ich arbeite an einer Website für eine große Organisation mit einer übergreifenden zentralen CSS. Sie könnten einen Stil haben wie
Um das zu überschreiben, müsste ich die Spezifität erreichen und mein CSS später laden oder die Spezifität übertreffen. Wenn das Markup außer meiner Kontrolle ist und es keine anderen Klassen gibt, habe ich Pech gehabt.
Ich könnte es jedoch einfach einem Layer hinzufügen. Layered Styles schlagen unlayered, also könnte meine Überschreibung einfach sein
Natürlich wäre für einen einzelnen Fall wie diesen Inline-Style der richtige Weg, aber es wird nützlicher, wenn mehr Deklarationen benötigt werden.
Ein weiteres Beispiel ist, wenn Sie CSS von Drittanbietern importieren. Sie könnten das alles in einen
@third-partyLayer packen und dann einen@third-party-overrideLayer verwenden, um Änderungen vorzunehmen.Ja, das scheint keine gute Sache zu sein. Es fühlt sich an, als würde es die gleichen Probleme einführen wie das Hinzufügen von !important zu allem.
Außerdem, in diesem Beispiel, könnten Sie nicht einfach eine Klasse wiederholen, um die Spezifität zu erhöhen?
Ich sehe, dass dies potenziell ein Nettonegativ ist, da dies eine zusätzliche Ebene der Komplexität in den Spezifitätskriegen hinzufügt. Ich stelle mir vor, dass Drittanbieter-Komponenten vollständig „gelayerte“ Stile haben werden, weil sie nicht möchten, dass sie überschrieben werden, und dann werden Entwickler damit beauftragt, sie zu überschreiben.
Das habe ich mir auch gedacht.
Wenn Sie einen Layer erstellen, um deren Layer zu überschreiben, bevor Sie deren Layer einbinden, gewinnen Sie. Es sei denn, die Drittanbieter-Komponenten haben eine Möglichkeit, ihren Layer zuerst definieren zu lassen (vielleicht durch JavaScript injiziert?), haben sie keinen Mechanismus, um die Sache zu erzwingen.
Nun, ich kann mir vorstellen, dass etwas wie Next/Nuxt/etc. das erzwingen kann, aber ich sehe nicht viel Styling von solchen Frameworks.
Sie müssen Ihren Layer nicht zuerst deklarieren, also müssen Sie sich darüber keine Sorgen machen.
Wenn Sie einen Layer überschreiben möchten, lassen Sie Ihren Layer einfach danach kommen, genau wie die übliche kaskadierende Überschreibung, die CSS seinen Namen gab.
Und da unlayered Regeln im letzten Entwurf (Oktober 2021) jetzt Priorität haben, scheint es noch einfacher zu werden.
Sieht so aus, als wäre
@layerdas neue!important:PIch sehe Leute in den Kommentaren hier Vergleiche mit
!importantmachen… Ich denke, das ist ein fairer Vergleich, denn das ist eines der Werkzeuge, die wir derzeit am ehesten mit Layern vergleichen können.Ich denke jedoch, dass dies ein zu enger Vergleich ist. Wenn Ihr CSS im Laufe der Zeit ziemlich statisch ist und Sie alles kontrollieren, bringen Layer möglicherweise keinen großen Vorteil (obwohl das noch abzuwarten ist, da es einen neuen strukturellen Aspekt von CSS bietet).
Aber wenn Sie 3rd-Party-CSS oder ein internes, gemeinsam genutztes CSS verwenden, können Layer diese Stile vereinfachen (z. B. schauen Sie sich die Stile von Bootstrap an, die überall
!importanthaben), da sie sich darauf verlassen können, dass der Entwickler sein eigenes CSS in einen niedrigeren Layer legt, oder sie könnten schließlich ihr CSS in einem vordefinierten Layer ausliefern und es den Entwicklern ermöglichen, es nach Bedarf in ihre CSS-Hierarchie zu positionieren.Ich denke, Layer werden die Notwendigkeit von
!importantin unserem eigenen CSS und in Drittanbieter-CSS entfernen. Sie fügen der Kaskade eine weitere Dimension hinzu, die im Makromaßstab funktioniert, wodurch wir die Selektorspezifität und die Selektorreihenfolge verwenden können, um Dinge im Mikromaßstab abzustimmen.Ich halte das für eine großartige Funktion!
Genau. Das Problem mit
!importantwar, dass es deklarationsspezifisch war und in jedem beliebigen Kontext der Kaskade auftauchen und dabei andere Spezifitätsfaktoren auslöschen konnte.@layerist weit davon entfernt. Es ermöglicht Ihnen, die Spezifität im Gottesmodus auf Makromaßstab zu verwalten. Wir werden in der Lage sein, die gesamte Architektur eines Projekts zu berücksichtigen, äußere Grenzen für die Spezifität festzulegen, und dann die „Mitglieder“ einzelner Layer gegeneinander antreten zu lassen.Ich freue mich definitiv darauf.
Dieses CSS-Layer-Ding ist wirklich interessant, keine Frage.
Aber… Welches Problem versuchen sie überhaupt zu lösen?
Ich habe die Sortierreihenfolge nicht verstanden. Wird sie immer noch basierend auf der Deklarationssortierreihenfolge bestimmt?
Es klingt, als wären sie etwas Ähnliches wie Namespaces. Wir werden Dinge im Geltungsbereich bestimmter Namespaces überschreiben können.
Sieht so aus, als ob die neueste Safari Technology Preview (Release 132) CSS Cascade Layers als experimentelle Funktion enthält (Develop → Experimental Feature → CSS Cascade Layers).
Sieht für mich aus wie
@import, aber inline.Aus der Perspektive der Barrierefreiheit frage ich mich, wie sich @layer auf Personen auswirken wird, die benutzerdefinierte Stylesheets verwenden.
Wir sind weit davon entfernt, Experten für Barrierefreiheit zu sein, aber wir denken viel über Browsererweiterungen und Ähnliches nach und glauben, dass dies auf lange Sicht ein Netto-Vorteil sein wird, aber kurzfristig einige Skripte neu geschrieben werden müssen. In Zukunft sollte es einfach sein, Benutzerstile in einem höheren Layer zu schreiben, sodass Ihre Stile immer angewendet werden.
„Es ermöglicht Ihnen, die Spezifität im Gottesmodus auf Makromaßstab zu verwalten“
Perfekt ausgedrückt.
Einige SaaS-Software ermöglicht es Ihnen, Ihr eigenes benutzerdefiniertes CSS hinzuzufügen, um die App über einem Basis-CSS-Theme zu „thematisieren“, das nicht entfernt werden kann. Oft lässt die Wahl der CSS-Selektoren zu wünschen übrig. @layers sind in diesem Fall perfekt, Sie können das einfach bereinigen und neu beginnen. Es sei denn, ich habe meine Layer durcheinander gebracht ;)
Sind Layer mit JavaScript nutzbar?
Ich sehe eine positive Seite dieser Funktion in Bezug auf die Möglichkeit, Basis-CSS, Resets usw. zu „sortieren“.
Aber wenn Sie überall in Ihrem Code einen Layer erstellen können, bedeutet das dann nicht, dass es eine Funktion ist, die die Funktionalität von
z-indexdupliziert?Ich glaube, das ist es.
Ich begann 2003 mit dem Schreiben von CSS2-Stylesheets, hatte aber nur oberflächliche Kenntnisse von JS bis 2013-15 (modest fortschreitend bis 2018).
Da ich 10-12 Jahre mehr Erfahrung in CSS hatte, verstand ich selbst, als ich Scope in JS verstanden hatte, nicht, worum es so ging, Dinge (einige Dinge, viele Dinge, alles) nicht beiläufig in den globalen Scope zu legen.
Rückblickend fällt mir ein, dass dies daran lag, dass in einem CSS-Stylesheet – dem Paradigma, mit dem ich viel vertrauter war – *alles* (wenn man Medienabfragen nicht als Quasi-Scope zählt) im globalen Scope liegt.
Also habe ich mein JS global gescoped, so wie ich mein CSS global gescoped habe – und habe erst später besser gelernt.
Aber mit der Einführung von CSS Cascade Layers gibt es jetzt einen CSS-Global-Scope: unlayered Styles.
So wie global gescoped Variablen in der JS Best Practice nur selten vorkommen, werden in der potenziellen zukünftigen CSS Best Practice
@layerüberall eingesetzt, um sicherzustellen, dass auch global gescoped Styles selten vorkommen.Dieser Ansatz würde bedeuten, dass, mangels sehr guter Gründe, keine Stile unlayered sein sollten und CSS Cascade Layers stattdessen ein fester Bestandteil der meisten Stylesheets werden würden, neben z.B. CSS Custom Properties und Touchscreen Media Queries.
Die Frage „Aber wann sollte ich
@layerverwenden?“ erinnert (einigermaßen) an die Frage „Aber wann sollte ichconstverwenden?“ nach der Einführung vonletundconstin ES2015.Erst als ein fortschrittlicheres Verständnis aufkam, formulierten viele ES2015-Entwickler diese Frage um als: „Wann sollte ich
constnicht verwenden?“Vielleicht ist das also die Lösung. Vielleicht werden wir, anstatt zu fragen, wann wir Cascade Layers verwenden sollten, enorm davon profitieren,
@layerflächendeckend einzuführen und zu erkennen, dass die wichtigere Frage, die jeder von uns stellen könnte, lautet: