Hojas de estilo para construir

Estilos reutilizables sin inconvenientes

Los hojas de estilo componibles son una forma de crear y distribuir estilos reutilizables cuando se usa DOM sombreado.

Navegadores compatibles

  • Chrome: 73.
  • Edge: 79.
  • Firefox: 101.
  • Safari: 16.4.

Origen

Siempre fue posible crear hojas de estilo con JavaScript. Sin embargo, históricamente, el proceso ha sido crear un elemento <style> con document.createElement('style') y, luego, acceder a su propiedad de hoja para obtener una referencia a la instancia subyacente de CSSStyleSheet. Este método puede producir código CSS duplicado y su aumento asociado, y el acto de adjuntar genera un flash de contenido sin diseño, ya sea que haya aumento o no. La interfaz CSSStyleSheet es la raíz de una colección de interfaces de representación de CSS, conocidas como CSSOM, que ofrece una forma programática de manipular los diseños de página, además de eliminar los problemas asociados con el método anterior.

Diagrama que muestra la preparación y aplicación del CSS.

Las hojas de estilo componibles permiten definir y preparar estilos de CSS compartidos y, luego, aplicarlos a varias raíces de sombras o al documento de forma fácil y sin duplicaciones. Las actualizaciones de un CSSStyleSheet compartido se aplican a todas las raíces en las que se adoptó, y adoptar un diseño de página es rápido y síncrono una vez que se carga la hoja.

La asociación establecida por los CSS componibles se adapta bien a una gran variedad de aplicaciones. Se puede usar para proporcionar un tema centralizado que usen muchos componentes: el tema puede ser una instancia de CSSStyleSheet que se pasa a los componentes, con actualizaciones del tema que se propagan a los componentes automáticamente. Se puede usar para distribuir valores de propiedad personalizada de CSS a subárboles de DOM específicos sin depender de la cascada. Incluso se puede usar como una interfaz directa para el analizador de CSS del navegador, lo que facilita la carga previa de hojas de estilo sin insertarlas en el DOM.

Cómo crear una hoja de estilo

En lugar de presentar una API nueva para lograrlo, la especificación de hojas de estilo componibles permite crear hojas de estilo de manera imperativa invocando el constructor CSSStyleSheet(). El objeto CSSStyleSheet resultante tiene dos métodos nuevos que hacen que sea más seguro agregar y actualizar reglas de hoja de estilo sin activar el destello de contenido sin diseño (FOUC). Los métodos replace() y replaceSync() reemplazan la hoja de estilo por una cadena de CSS, y replace() muestra una promesa. En ambos casos, no se admiten referencias de hojas de estilo externas. Se ignoran todas las reglas @import y se generará una advertencia.

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

Cómo usar hojas de estilo construidas

La segunda función nueva que presentan los StyleSheets componibles es una propiedad adoptedStyleSheets disponible en Shadow Roots y Documents. Esto nos permite aplicar de forma explícita los estilos definidos por un CSSStyleSheet a un subárbol DOM determinado. Para ello, configuramos la propiedad en un array de uno o más hojas de estilo para aplicarlas a ese 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);

Revisión general

Con los editores de hojas de estilo componibles, los desarrolladores web ahora tienen una solución explícita para crear hojas de estilo CSS y aplicarlas a árboles de DOM. Tenemos una nueva API basada en promesas para cargar hojas de estilo desde una cadena de fuente de CSS que usa el analizador integrado del navegador y la semántica de carga. Por último, tenemos un mecanismo para aplicar actualizaciones de la hoja de estilo a todos los usos de una hoja de estilo, lo que simplifica elementos como los cambios de tema y las preferencias de color.

Ver demostración

Con la mirada puesta en el futuro

La versión inicial de los diseños de página componibles se envió con la API que se describe aquí, pero se está trabajando para facilitar su uso. Hay una propuesta para extender adoptedStyleSheets FrozenArray con métodos dedicados para insertar y quitar hojas de estilo, lo que evitaría la necesidad de clonar arrays y evitaría posibles referencias de hojas de estilo duplicadas.

Más información