Folhas de estilo construíveis

Estilos reutilizáveis e integrados.

As folhas de estilo construtáveis são uma maneira de criar e distribuir estilos reutilizáveis ao usar o Shadow DOM.

Compatibilidade com navegadores

  • 73
  • 79
  • 101
  • 16.4

Origem

Sempre foi possível criar folhas de estilo usando JavaScript. No entanto, historicamente, o processo era criar um elemento <style> usando document.createElement('style') e acessar a propriedade da planilha para conseguir uma referência à instância CSSStyleSheet. Esse método pode produzir código CSS duplicado e a sobrecarga correspondente, e o ato de anexar leva a um flash de conteúdo sem estilo, independentemente de haver excesso ou não. A interface CSSStyleSheet é a raiz de uma coleção de interfaces de representação CSS, chamadas de CSSOM, que oferece uma maneira programática de manipular folhas de estilo e eliminar os problemas associados ao método antigo.

Diagrama mostrando a preparação e a aplicação do CSS.

Com as folhas de estilo construíveis, é possível definir e preparar estilos CSS compartilhados e, em seguida, aplicá-los a várias raízes paralelas ou ao documento com facilidade e sem duplicação. As atualizações em uma CSSStyleSheet compartilhada são aplicadas a todas as raízes em que foi adotada, e a adoção de uma folha de estilo é rápida e síncrona depois que a planilha é carregada.

A associação configurada por folhas de estilo construtáveis funciona bem para vários aplicativos diferentes. Ele pode ser usado para fornecer um tema centralizado usado por muitos componentes: o tema pode ser uma instância CSSStyleSheet transmitida para componentes, com atualizações do tema propagadas automaticamente para os componentes. Ele pode ser usado para distribuir valores de propriedade personalizada de CSS para subárvores específicas do DOM sem depender da cascata. Ele pode até ser usado como uma interface direta para o analisador de CSS do navegador, facilitando o pré-carregamento de folhas de estilo sem injetá-las no DOM.

Como criar uma folha de estilo

Em vez de introduzir uma nova API para fazer isso, a especificação Constructable Stylesheets permite criar folhas de estilo de forma imperativa invocando o construtor CSSStyleSheet(). O objeto CSSStyleSheet resultante tem dois novos métodos que tornam mais seguro adicionar e atualizar regras de folha de estilo sem acionar Flash de conteúdo sem estilo (FOUC, na sigla em inglês). Os métodos replace() e replaceSync() substituem a folha de estilo por uma string de CSS, e replace() retorna uma promessa. Em ambos os casos, as referências externas da folha de estilo não são compatíveis. Todas as regras @import são ignoradas e produzirão um aviso.

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..."

Como usar folhas de estilo construídas

O segundo novo recurso apresentado pelo recurso "Buildable StyleSheet" é uma propriedade adoptedStyleSheets disponível em Shadow Roots e Documents. Isso permite aplicar explicitamente os estilos definidos por um CSSStyleSheet a determinada subárvore do DOM. Para isso, definimos a propriedade como uma matriz de uma ou mais folhas de estilo a serem aplicadas a esse elemento.

// 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