Konstrualne arkusze stylów

Bezproblemowe style wielokrotnego użytku.

Konstruowalne arkusze stylów to sposób na tworzenie i rozpowszechnianie stylów wielokrotnego użytku w Shadow DOM.

Obsługa przeglądarek

  • 73
  • 79
  • 101
  • 16.4

Źródło

Od zawsze możliwe było tworzenie arkuszy stylów za pomocą języka JavaScript. Do tej pory proces ten polegał jednak na tworzeniu elementu <style> za pomocą document.createElement('style'), a następnie uzyskiwaniu dostępu do właściwości jego arkusza w celu uzyskania odniesienia do bazowej instancji CSSStyleSheet. Ta metoda może skutkować zduplikowaniem kodu CSS i jego zdublowanym nalotem, a dołączenie do niego prowadzi do błyśnięcia niesformatowanej treści niezależnie od tego, czy jest ona wzbogacona czy nie. Interfejs CSSStyleSheet to podstawowa część zbioru interfejsów do reprezentacji CSS (tzw. CSSOM). Umożliwia on zautomatyzowaną obsługę arkuszy stylów, a także eliminuje problemy związane ze starą metodą.

Diagram przedstawiający przygotowanie i zastosowanie usługi porównywania cen.

Możliwe do budowania arkusze stylów umożliwiają definiowanie i przygotowywanie wspólnych stylów CSS, a następnie stosowanie tych stylów do wielu źródeł cienia lub dokumentu bez powielania ich. Aktualizacje udostępnionego arkusza CSSStyleSheet są stosowane do wszystkich elementów głównych, do których został on przyjęty, a zastosowanie arkusza stylów odbywa się szybko i synchronicznie po wczytaniu arkusza.

Powiązanie konfigurowane przez arkusze stylów do konstrukcji sprawdza się w wielu różnych zastosowaniach. Można go wykorzystać do uzyskania scentralizowanego motywu, który jest wykorzystywany przez wiele komponentów. Może to być instancja CSSStyleSheet przekazywana do komponentów, a aktualizacje motywu są rozpowszechniane automatycznie w komponentach. Można go używać do rozdzielania wartości niestandardowej właściwości CSS w określonych poddrzewach DOM bez korzystania z kaskady. Można go nawet używać jako bezpośredniego interfejsu parsera CSS przeglądarki, co ułatwia wstępne wczytywanie arkuszy stylów bez wstrzykiwania ich do DOM.

Tworzenie arkusza stylów

Zamiast wprowadzać w tym celu nowy interfejs API, specyfikacja Constructable StyleSheets umożliwia tworzenie arkuszy stylów imperatywnie przez wywołanie konstruktora CSSStyleSheet(). Powstały obiekt CSSStyleSheet ma 2 nowe metody, które ułatwiają dodawanie i aktualizowanie reguł arkusza stylów bez wywoływania funkcji Flash of Unstyled Content (FOUC). Zarówno metody replace(), jak i replaceSync() zastępują arkusz stylów ciągiem CSS, a metoda replace() zwraca obietnicę. W obu przypadkach odwołania do zewnętrznych arkuszy stylów nie są obsługiwane – reguły @import są ignorowane i generują ostrzeżenie.

const sheet = new CSSStyleSheet();

// replace all styles synchronously:
sheet.replaceSync('a { color: red; }');

// replace all styles:
sheet.replace('a { color: blue; }')
  .then(() => {
    console.log('Styles replaced');
  })
  .catch(err => {
    console.error('Failed to replace styles:', err);
  });

// Any @import rules are ignored.
// Both of these still apply the a{} style:
sheet.replaceSync('@import url("styles.css"); a { color: red; }');
sheet.replace('@import url("styles.css"); a { color: red; }');
// Console warning: "@import rules are not allowed here..."

Korzystanie z utworzonych arkuszy stylów

Drugą nową funkcją wprowadzoną przez Constructable StyleSheets jest właściwość adoptedStyleSheets dostępna w Shadow Roots i Dokumentach. Dzięki temu możemy bezpośrednio zastosować style zdefiniowane przez CSSStyleSheet do danego poddrzewa DOM. W tym celu ustawimy właściwość na tablicę co najmniej 1 arkusza stylów do zastosowania do danego elementu.

// Create our shared stylesheet:
const sheet = new CSSStyleSheet();
sheet.replaceSync('a { color: red; }');

// Apply the stylesheet to a document:
document.adoptedStyleSheets.push(sheet);

// Apply the stylesheet to a Shadow Root:
const node = document.createElement('div');
const shadow = node.attachShadow({ mode: 'open' });
shadow.adoptedStyleSheets.push(sheet);

Putting it all together

With Constructable StyleSheets, web developers now have an explicit solution for creating CSS StyleSheets and applying them to DOM trees. We have a new Promise-based API for loading StyleSheets from a string of CSS source that uses the browser's built-in parser and loading semantics. Finally, we have a mechanism for applying stylesheet updates to all usages of a StyleSheet, simplifying things like theme changes and color preferences.

View Demo

Looking ahead

The initial version of Constructable Stylesheets shipped with the API described here, but there's work underway to make things easier to use. There's a proposal to extend the adoptedStyleSheets FrozenArray with dedicated methods for inserting and removing stylesheets, which would obviate the need for array cloning and avoid potential duplicate stylesheet references.

More information