Skip to content
Dev Tech
  • Home
  • Tech

Constructable Stylesheets

February 23, 2022 Article

Seamless reusable styles.

Feb 8, 2019 — Updated Feb 23, 2022

Constructable Stylesheets are a way to create and distribute reusable styles when using Shadow DOM.

Constructable Stylesheets are available in Chromium (versions 73 and higher), and in Firefox from version 75 behind the layout.css.constructable-stylesheets.enabled flag.

It has always been possible to create stylesheets using JavaScript. However, the process has historically been to create a

Constructing a stylesheet #

Rather than introducing a new API to accomplish this, the Constructable StyleSheets specification makes it possible to create stylesheets imperatively by invoking the CSSStyleSheet() constructor. The resulting CSSStyleSheet object has two new methods that make it safer to add and update stylesheet rules without triggering Flash of Unstyled Content (FOUC). The replace() and replaceSync() methods both replace the stylesheet with a string of CSS, and replace() returns a Promise. In both cases, external stylesheet references are not supported—any @import rules are ignored and will produce a warning.

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

Gotchas

In earlier versions of the specification, replace() allowed @import rules and returned a Promise that resolved when these were finished loading. This feature was removed from the specification and @import rules are ignored with a warning as of Chrome 84.

Using constructed stylesheets #

The second new feature introduced by Constructable StyleSheets is an adoptedStyleSheets property available on Shadow Roots and Documents. This lets us explicitly apply the styles defined by a CSSStyleSheet to a given DOM subtree. To do so, we set the property to an array of one or more stylesheets to apply to that element.

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

// Apply the stylesheet to a document:
document.adoptedStyleSheets = [sheet];

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

Notice that we're overriding the value of adoptedStyleSheets instead of changing the array in place. This is required because the array is frozen; in-place mutations like push() throw an exception, so we have to assign a new array. To preserve any existing StyleSheets added via adoptedStyleSheets, we can use concat to create a new array that includes the existing sheets as well as additional ones to add:

const sheet = new CSSStyleSheet();
sheet.replaceSync('a { color: red; }');

// Combine existing sheets with our new one:
document.adoptedStyleSheets = [...document.adoptedStyleSheets, 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 #

Last updated: Feb 23, 2022— Improve article
READ Also :   Serve responsive images

Calendar

March 2022
M T W T F S S
 123456
78910111213
14151617181920
21222324252627
28293031  
« Feb    

Archives

  • March 2022
  • February 2022
  • January 2022
  • November 2021
  • October 2021
  • August 2021
  • July 2021
  • June 2021

Categories

  • Improve article
  • Performance
  • Tech
  • Uncategorized
  • Wordpress

Copyright Dev Tech 2022 | By Theme in Progress | Proudly powered by WordPress

en_USEnglish
id_IDIndonesian en_USEnglish