Eine der größten Schwierigkeiten von CSS kommt gleich zu Anfang, nämlich das “C”. Die Stylesheets sind cascading, sie kaskadieren. Und in diese Kaskade spielen eine ganze Reihe von Faktoren hinein: Wo kommen die Stylesheets her (style-Tags im Unterschied zu eingebundenen CSS-Dateien), in welcher Reihenfolge stehen die Stylesheets, wie spezifisch sind die Selektoren und so weiter. Es kann schwer sein, das Ergebnis vorherzusagen, und bereits kleine Änderungen können alles auf den Kopf stellen. Wenn man dann noch mit !important arbeitet, hat das häufig mehr mit “Entwickeln mit der Brechstange” zu tun als mit zielgenauem Arbeiten.

Die At-Rule @scope schafft hier zumindest ein Stück weit Abhilfe. Mit @scope kann man, vereinfacht ausgedrückt, den Gültigkeitsbereich von Stylesheets definieren. Standardmäßig umfasst der sogenannte Selektionskontext das gesamte Dokument. Das bedeutet, alle Selektoren werden relativ zum Wurzelelement des Dokuments angewandt. Wenn man beispielsweise die folgenden Stylesheets hat

p {
  color: darkblue;
}

wird die Schrift in allen p-Tags im gesamten Dokument blau. Soweit, so wenig überraschend.

Mit Hilfe von @scope kann man den Selektionskontext selbst definieren. Mit

@scope (.container) {
  p {
    color: darkblue;
  }
}

werden nur diejenigen p-Tags blau, die innerhalb eines Blockelements mit der Klasse container liegen.

Das war natürlich auch bisher schon möglich, etwa mit

.container p {
  color: darkblue;
}

Das hat allerdings zwei Nachteile: Man muss die Selektoren häufig ziemlich exakt an der Struktur des Markup “entlangprogrammieren”. Ändert sich die Struktur, wird in der Regel auch eine Änderung am CSS fällig. Und die Selektoren werden oft ziemlich spezifisch, und Spezifität ist wie erwähnt ein wichtiger Faktor bei der Kaskadierung. Wenn man also seine Selektoren relativ spezifisch machen muss, verliert man an Flexibilität.

@scope kann bei diesen Problemen eine Alternative sein, und seit etwa Ende letzten Jahres ist die At-Regel Baseline (sprich, in den neuesten Versionen aller wichtigen Browser unterstützt). Außerdem kann man mit @scope besonders klar Stylesheets für Komponenten definieren. Denn diese Styles sollten natürlich nicht in den Rest des Dokuments “ausbluten”.

Nehmen wir beispielsweise eine Komponente mit der folgenden Struktur

<div class="posting">
  <p class="title">Title</p>
  <p class="author">Author</p>
  <div class="body">Body</div>
</div>

Die können wir komplett analog stylen mit

@scope (.posting) {
  :scope {
    border: solid 2px darkgray;
  }

  .title {
    font-weight: bold;
  }

  .author {
    font-size: smaller;
  }

  .body {
    background-color: #fcfcfc;
  }
}

Dabei müssen wir nicht befürchten, dass die Stylesheets für .title, .author und so weiter sich auf den Rest der Seite auswirken.

@scope kann noch mehr. Beispielsweise kann man bestimmte Bereiche ausnehmen, zum Beispiel für Subkomponenten. Wenn im obigen Beispiel der Body des Postings eine eigene Komponente ist, kann man sie vom Styling der übergeordneten Komponente ausnehmen:

@scope (.posting) to (.body) {
  :scope {
    border: solid 2px darkgray;
  }

  .title {
    font-weight: bold;
  }

  .author {
    font-size: smaller;
  }
}

Insgesamt bietet @scope interessante neue Möglichkeiten, CSS zielgenauer, besser lesbar und besser wartbar zu gestalten.