Hojas de estilo para construir

Estilos reutilizables sin problemas

Las hojas de estilo construibles son una forma de crear y distribuir diseños reutilizables cuando se usa el DOM Shadow.

Navegadores compatibles

  • 73
  • 79
  • 101
  • 16.4

Origen

Siempre se ha podido crear hojas de estilo con JavaScript. Sin embargo, históricamente, el proceso consistía en crear un elemento <style> con document.createElement('style') y, luego, acceder a su propiedad de hoja para obtener una referencia a la instancia CSSStyleSheet subyacente. Este método puede generar código CSS duplicado y su sobredimensionamiento, y el acto de adjuntar genera un destello de contenido sin estilo, independientemente de que esté sobrecargado o no. La interfaz CSSStyleSheet es la raíz de una colección de interfaces de representación de CSS denominadas CSSOM, que ofrece una forma programática de manipular las hojas de estilo y eliminar los problemas asociados con el método anterior.

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

Las hojas de estilo constructibles permiten definir y preparar los diseños CSS compartidos y, luego, aplicar esos estilos a varias shadow roots o al documento con facilidad y sin duplicación. Las actualizaciones de una CSSStyleSheet compartida se aplican a todas las raíces en las que se adoptó, y la adopción de una hoja de estilo es rápido y síncrono una vez que la hoja se carga.

La asociación configurada por las hojas de estilo constructibles se presta bien a una serie de aplicaciones diferentes. Se puede usar para proporcionar un tema centralizado utilizado por muchos componentes: el tema puede ser una instancia CSSStyleSheet que se pasa a los componentes, con actualizaciones del tema que se propagan automáticamente a los componentes. Se puede usar para distribuir valores de propiedades personalizadas de CSS en subárboles del DOM específicos sin depender de la cascada. Incluso se puede usar como una interfaz directa con el analizador de CSS del navegador, lo que facilita la precarga de hojas de estilo sin insertarlas en el DOM.

Construcción de una hoja de estilo

En lugar de introducir una nueva API para lograrlo, la especificación ConstructableStyleSheets permite crear hojas de estilo de manera imperativa al invocar el constructor CSSStyleSheet(). El objeto CSSStyleSheet resultante tiene dos métodos nuevos que hacen que sea más seguro agregar y actualizar reglas de hojas de estilo sin activar Flash de contenido sin estilo (FOUC). Los métodos replace() y replaceSync() reemplazan la hoja de estilo con una cadena de CSS, y replace() muestra una promesa. En ambos casos, no se admiten referencias a hojas de estilo externas; se ignorará cualquier regla @import y se producirá 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 presenta Constructable StyleSheets es una propiedad adoptedStyleSheets, que está disponible en Shadow Roots y Documentos. Esto nos permite aplicar de manera explícita los estilos definidos por un CSSStyleSheet a un subárbol del DOM determinado. Para ello, configuramos la propiedad en un array de una o más hojas de estilo para aplicar 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

Gracias a Constructable StyleSheets, los desarrolladores web ahora tienen una solución explícita para crear hojas de estilo de CSS y aplicarlas a los árboles del 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, contamos con un mecanismo para aplicar actualizaciones de la hoja de estilo a todos los usos de esta, lo que simplifica aspectos 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 las hojas de estilo Constructable se incluyó con la API que se describe aquí, pero se está trabajando en hacer todo más fácil de usar. Hay una propuesta para extender adoptedStyleSheets FrozenArray con métodos dedicados para insertar y quitar hojas de estilo, lo que omitiría la necesidad de clonar arrays y evitaría posibles referencias de hojas de estilo duplicadas.

Más información