Start · Sprachen · JavaScript · Referenz · CSSLayerStatementRule

CSSLayerStatementRule

Schnittstelle

Steht für eine <code>@layer</code>-Anweisung ohne Block, z. B. <code>@layer reset, base, components;</code>. Sie legt nur Namen und Reihenfolge von Kaskadenebenen fest.

seit JavaScript Baseline 2022: Chrome 99, Edge 99, Firefox 97, Saf Kategorie: webapi

Signatur

interface CSSLayerStatementRule extends CSSRule

Beschreibung

CSSLayerStatementRule ist das CSSOM-Objekt für eine @layer-Anweisung ohne Block. Eine solche Regel deklariert eine oder mehrere Kaskadenebenen (cascade layers) und legt dabei ihre Reihenfolge fest, zum Beispiel @layer reset, base, components, utilities;. Stile enthält sie selbst nicht. Die Ebenen werden erst später mit @layer name { … }-Blöcken (CSSLayerBlockRule) oder über @import url(…) layer(name) gefüllt.

Die Schnittstelle erbt von CSSRule. Neu dazu kommt nur die schreibgeschützte Eigenschaft nameList: ein eingefrorenes Array mit den Ebenennamen in der Reihenfolge, in der sie deklariert wurden. Verschachtelte Namen stehen dort in Punktschreibweise, etwa "framework.base".

Das Interface braucht man vor allem bei der Analyse von Stylesheets zur Laufzeit. Beispiele sind Entwicklerwerkzeuge, Linter, Design-System-Prüfungen oder die Frage, in welcher Reihenfolge ein Framework seine Ebenen festlegt. Solche Regeln findet man, indem man document.styleSheets bzw. CSSStyleSheet.cssRules durchläuft und mit instanceof CSSLayerStatementRule prüft.

Als Nächstes erzeugt man diese Regeln oft selbst, etwa mit CSSStyleSheet.insertRule() oder replaceSync() in einem konstruierbaren Stylesheet. So kann man die Reihenfolge der Ebenen festlegen, bevor weitere Stile geladen werden.

Parameter

Name Typ Default Beschreibung
$nameList ReadonlyArray<string> Schreibgeschützte Instanzeigenschaft, kein Konstruktor-Parameter: ein eingefrorenes Array mit den deklarierten Ebenennamen in Reihenfolge der Deklaration.
$cssText string Von CSSRule geerbt: die serialisierte Regel, z. B. "@layer reset, base;".
$parentStyleSheet CSSStyleSheet | null Von CSSRule geerbt: das Stylesheet, in dem die Regel steht.
$parentRule CSSRule | null Von CSSRule geerbt: die umschließende Regel, z. B. eine CSSLayerBlockRule oder CSSMediaRule, sonst null.

Rückgabewert

Typ
CSSLayerStatementRule
Beschreibung
Instanzen gibt es nur über das CSSOM, etwa als Einträge von CSSStyleSheet.cssRules. Einen öffentlichen Konstruktor hat das Interface nicht.

Beispiele

Ebenen-Reihenfolge aus einem Stylesheet auslesen

// Im HTML: <style>@layer reset, base, components; @layer base { body { margin: 0; } }</style>
const sheet = document.styleSheets[0];

for (const rule of sheet.cssRules) {
  if (rule instanceof CSSLayerStatementRule) {
    console.log('Deklarierte Ebenen:', rule.nameList);
    console.log('cssText:', rule.cssText);
  }
}
Deklarierte Ebenen: ['reset', 'base', 'components'] cssText: @layer reset, base, components;

Anweisung per Konstruierbarem Stylesheet anlegen und prüfen

const sheet = new CSSStyleSheet();
sheet.replaceSync(`
  @layer reset, framework.base, utilities;
  @layer utilities { .hidden { display: none; } }
`);
document.adoptedStyleSheets = [...document.adoptedStyleSheets, sheet];

const [statement, block] = sheet.cssRules;
console.log(statement.constructor.name); // Anweisung ohne Block
console.log(block.constructor.name);     // Block-Regel
console.log(statement.nameList);
console.log(Object.isFrozen(statement.nameList));
CSSLayerStatementRule CSSLayerBlockRule ['reset', 'framework.base', 'utilities'] true

Alle Ebenen-Deklarationen rekursiv sammeln (auch in @media)

const collectLayerOrder = (rules, result = []) => {
  for (const rule of rules) {
    if (rule instanceof CSSLayerStatementRule) {
      result.push(...rule.nameList);
    } else if ('cssRules' in rule) {
      // Verschachtelte Regeln wie @media, @supports, @layer { }
      collectLayerOrder(rule.cssRules, result);
    }
  }
  return result;
};

const sheet = new CSSStyleSheet();
sheet.replaceSync(`
  @layer reset, base;
  @media (min-width: 600px) { @layer layout; }
`);
console.log(collectLayerOrder(sheet.cssRules));
['reset', 'base', 'layout']

Reihenfolge vor anderen Stilen per insertRule festlegen

const style = document.createElement('style');
document.head.prepend(style); // möglichst früh, damit die Reihenfolge zuerst feststeht

style.sheet.insertRule('@layer reset, vendor, app;', 0);
const rule = style.sheet.cssRules[0];
console.log(rule instanceof CSSLayerStatementRule, rule.nameList.length);
true 3

// Wichtig · Fallstricke

  • Anweisung und Block unterscheiden: @layer a, b; wird zu einer CSSLayerStatementRule (Eigenschaft nameList). @layer a { … } wird zu einer CSSLayerBlockRule (Eigenschaften name und cssRules). Beide leiten sich direkt von CSSRule ab, nicht voneinander.
  • nameList ist schreibgeschützt und eingefroren. Wer die Reihenfolge ändern will, muss die Regel mit deleteRule() entfernen und mit insertRule() neu einfügen.
  • Die erste Nennung zählt: Eine Ebene wird dort eingeordnet, wo sie im Dokument zuerst vorkommt. Eine spätere @layer-Anweisung mit bereits bekannten Namen ändert deren Reihenfolge nicht mehr. Wird eine Anweisung erst nachträglich per Skript eingefügt, wirkt sie daher oft nicht wie erwartet.
  • Anonyme Ebenen: Eine Anweisung ohne Namen ist ungültig. Anonyme Ebenen gibt es nur als Block (@layer { … }).
  • Fremde Stylesheets: Bei Stylesheets von einer anderen Herkunft ohne CORS-Freigabe löst der Zugriff auf cssRules einen SecurityError aus. Deshalb die Abfrage in try/catch einschließen.
  • Kompatibilität: Seit März 2022 in allen aktuellen Browsern verfügbar (Chrome/Edge 99, Firefox 97, Safari 15.4). Ältere Browser ignorieren @layer komplett; dort fehlt das Interface. Vor der Nutzung mit typeof CSSLayerStatementRule !== 'undefined' prüfen.