A partial archive of discourse.wicg.io as of Saturday February 24, 2024.

ES6 Modules-style importing modularity for stylesheets


The following proposal is meant to address limitations with JavaScript modules that depend on CSS stylesheets such that they are prevented from acting in a fully modular yet performant manner. The web needs modular widgets. With more widgets becoming JavaScript based, in my view, there is not so much of a need for HTML imports (especially if one expresses one’s HTML within JavaScript) as there is for stylesheet imports within the language that can rule them all: JavaScript.

I’d like to see a standard means to indicate stylesheet dependencies within individual JavaScript widget-building files such that these imports are statically analyzable for immediate asynchronous downloading of stylesheets but which blocks HTML rendering (and JavaScript execution) until all such imports occur.

Ideally, these could be interspersed with ES6 Module imports such that:

// module-1.js
importStylesheet 'stylesheet1.css';
import m2 from 'module-2.js';
importStylesheet 'stylesheet3.css';

// module-2.js
importStylesheet 'stylesheet2.css';

…would load the stylesheets in any order but apply them in the cascading order:

  • stylesheet1.css
  • stylesheet2.css
  • stylesheet3.css

Tools like Rollup could strip out these stylesheet importing references to either build a single external CSS file or possibly insert a style tag dynamically with the contents at the beginning of the module, but even without bundling, performance benefits would be there, and web widgets (at least JavaScript-based ones) could finally become fully modular as with ES6 Modules. There’d also be no need for a proliferation of non-standard import directives meant to fill this gap.

(An optional standard for dynamic, parallel (or at least parallelizable-through-promises) run-time stylesheet importing (analogous to the import() proposal) would be nice too, without the extra hassle of a fetch-based solution, and while not having all of the benefits of static loading, it would allow for more choice among widget users about whether to apply stylesheets or not.)


My proposal for “import as” covers programmable import statements, which includes the ability to import and apply stylesheets.


There’s also CSS modules, which accomplish much the same that’s being proposed here, just a little more extension-aware. (It requires a .css extension, although that’s extensible via tooling.)

I don’t think that aims to become a web spec, though.


Me too.

I was porting my custom elements from Polymer 1 to Custom Elements 1, and I found that have to create a <style>my css rules here</style> element in the shadow root, instead of being able to create a <link rel="stylesheet" href="my.css"> , because the href resolves against the HTML page that is using the custom element, not against the module that creates the shadow root. The modules themselves resolve against the path of the main module. There should be some way to ship CSS files with a component and load them by reference instead of having to copy the CSS into the JS. I don’t even own the CSS, it comes from a dependency, so it becomes a build time issue I’m sure I will regret.

I believe this issue is also covered by this article