Konstrualne arkusze stylów

Płynne style wielokrotnego użytku.

Konstruktywne arkusze stylów umożliwiają tworzenie i rozpowszechnianie stylów wielokrotnego użytku za pomocą Shadow DOM.

Obsługa przeglądarek

  • 73
  • 79
  • 101
  • 16.4

Źródło

W przypadku JavaScriptu arkusze stylów zawsze można było tworzyć. W przeszłości proces ten polegał na utworzeniu elementu <style> za pomocą właściwości document.createElement('style'), a następnie uzyskania dostępu do właściwości „sheet”, aby uzyskać odniesienie do bazowego wystąpienia CSSStyleSheet. Ta metoda może spowodować zduplikowanie kodu CSS i powiązanego z nim zdublowanie, a dołączenie prowadzi do rozmycia treści bez stylu niezależnie od tego, czy jest jej zwielokrotnienie. Interfejs CSSStyleSheet jest podstawą zbioru interfejsów do reprezentacji CSS zwanych CSSOM, które umożliwiają zautomatyzowane manipulowanie arkuszami stylów oraz eliminowanie problemów związanych ze starą metodą.

Diagram przedstawiający przygotowanie i stosowanie CSS.

Konstruktalne arkusze stylów pozwalają łatwo definiować i przygotowywać wspólne style CSS, a następnie stosować je do wielu katalogów źródłowych lub dokumentu. Zmiany udostępnianego arkusza CSSStyleSheet są stosowane do wszystkich elementów głównych, do których został on zastosowany, a wdrażanie arkusza stylów przebiega szybko i synchronicznie po wczytaniu arkusza.

Powiązanie utworzone przez Constructable Stylesheets dobrze sprawdza się w wielu różnych zastosowaniach. Pozwala stworzyć scentralizowany motyw używany przez wiele komponentów: motywem może być instancja CSSStyleSheet przekazywana do komponentów, a aktualizacje motywu są przenoszone do komponentów automatycznie. Można go używać do rozdzielania wartości właściwości niestandardowej CSS do określonych poddrzew DOM bez korzystania z kaskady. Może być nawet używany jako bezpośredni interfejs do parsera CSS w przeglądarce, co ułatwia wstępne wczytywanie arkuszy stylów bez wprowadzania ich w interfejsie DOM.

Tworzenie arkusza stylów

Zamiast wprowadzać w tym celu nowy interfejs API, specyfikacja Constructable StyleSheets umożliwia imperatywne tworzenie arkuszy stylów przez wywołanie konstruktora CSSStyleSheet(). Powstały obiekt CSSStyleSheet ma 2 nowe metody, które zwiększają bezpieczeństwo dodawania i aktualizowania reguł arkusza stylów bez wywoływania funkcji Flash of Unstyled Content (FOUC). Metody replace() i replaceSync() zastępują arkusz stylów ciągiem CSS, a replace() zwraca obietnicę. W obu przypadkach odwołania do zewnętrznych arkuszy stylów nie są obsługiwane – wszystkie 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ą w Constructable StyleSheets jest właściwość adoptedStyleSheets dostępna w sekcjach ShadowRoots i Dokumenty. Umożliwia to jawne zastosowanie stylów zdefiniowanych przez zasadę CSSStyleSheet do danego poddrzewa DOM. Aby to zrobić, ustawiamy właściwość na tablicę z co najmniej jednym arkuszem stylów, którą stosujemy do tego 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