<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <id>https://web.dev/</id>
  <title>Dan Clark on web.dev</title>
  <updated>2026-04-15T23:21:06Z</updated>
  <author>
    <name>Dan Clark</name>
  </author>
  <link href="https://web.dev/authors/dandclark/feed.xml" rel="self"/>
  <link href="https://web.dev/"/>
  <icon>https://web-dev.imgix.net/image/ZDZVuXt6QqfXtxkpXcPGfnygYjd2/lYPo8w4ZwA465hg323uT.jpg?auto=format</icon>
  <logo>https://web.dev/images/shared/rss-banner.png</logo>
  <subtitle>Developer on the Microsoft Edge Web Platform team</subtitle>
  
  
  <entry>
    <title>Using CSS Module Scripts to import stylesheets</title>
    <link href="https://web.dev/css-module-scripts/"/>
    <updated>2021-08-17T00:00:00Z</updated>
    <id>https://web.dev/css-module-scripts/</id>
    <content type="html" mode="escaped">&lt;p&gt;With the new CSS module scripts feature, you can load CSS style sheets with &lt;code&gt;import&lt;/code&gt; statements,
just like &lt;a href=&quot;https://developer.mozilla.org/docs/Web/JavaScript/Guide/Modules&quot; rel=&quot;noopener&quot;&gt;JavaScript
modules&lt;/a&gt;. The style sheets
can then be applied to documents or &lt;a href=&quot;https://developer.mozilla.org/docs/Web/API/ShadowRoot&quot; rel=&quot;noopener&quot;&gt;shadow
roots&lt;/a&gt; in the same manner as
&lt;a href=&quot;https://web.dev/constructable-stylesheets/&quot;&gt;constructable
stylesheets&lt;/a&gt;. This can
be more convenient and &lt;a href=&quot;https://dandclark.github.io/json-css-module-notes/#css-module-performancememory-examples&quot; rel=&quot;noopener&quot;&gt;more
performant&lt;/a&gt;
than other ways of importing and applying CSS.&lt;/p&gt;
&lt;h2 id=&quot;browser-support&quot;&gt;Browser Support &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/css-module-scripts/#browser-support&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;CSS module scripts are available by default in Chrome and Edge in version 93.&lt;/p&gt;
&lt;p&gt;Support in Firefox and Safari is not yet available. Implementation progress can be tracked at the
&lt;a href=&quot;https://bugzilla.mozilla.org/show_bug.cgi?id=1720570&quot; rel=&quot;noopener&quot;&gt;Gecko bug&lt;/a&gt; and &lt;a href=&quot;https://bugs.webkit.org/show_bug.cgi?id=227967&quot; rel=&quot;noopener&quot;&gt;WebKit
bug&lt;/a&gt;, respectively.&lt;/p&gt;
&lt;h2 id=&quot;prerequisites&quot;&gt;Prerequisites &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/css-module-scripts/#prerequisites&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Familiarity with &lt;a href=&quot;https://developer.mozilla.org/docs/Web/JavaScript/Guide/Modules&quot; rel=&quot;noopener&quot;&gt;JavaScript
modules&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Familiarity with &lt;a href=&quot;https://web.dev/constructable-stylesheets/&quot;&gt;constructable
stylesheets&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;using-css-module-scripts&quot;&gt;Using CSS module scripts &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/css-module-scripts/#using-css-module-scripts&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Import a CSS module script and apply it to a document or a shadow root like this:&lt;/p&gt;
&lt;div&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; sheet &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;./styles.css&#39;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;assert&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;css&#39;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;document&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;adoptedStyleSheets &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;sheet&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;shadowRoot&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;adoptedStyleSheets &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;sheet&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;p&gt;The default export of a CSS module script is a &lt;a href=&quot;https://web.dev/constructable-stylesheets/&quot;&gt;constructable
stylesheet&lt;/a&gt; whose
contents are those of the imported file. Like any other constructable stylesheet, it is applied to
documents or shadow roots using
&lt;a href=&quot;https://wicg.github.io/construct-stylesheets/#using-constructed-stylesheets&quot; rel=&quot;noopener&quot;&gt;&lt;code&gt;adoptedStyleSheets&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Unlike other ways of applying CSS from JavaScript, there is no need to create &lt;code&gt;&amp;lt;style&amp;gt;&lt;/code&gt; elements or
mess with JavaScript strings of CSS text.&lt;/p&gt;
&lt;p&gt;CSS modules also have some of the same benefits as JavaScript modules.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Deduplication:&lt;/strong&gt; if the same CSS file is imported from multiple places in an application, it will
still only be fetched, instantiated, and parsed a single time.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Consistent order of evaluation:&lt;/strong&gt; when the importing JavaScript is running, it can rely on the
stylesheet it imports having already been fetched and parsed.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Security:&lt;/strong&gt; modules are fetched with &lt;a href=&quot;https://developer.mozilla.org/docs/Web/HTTP/CORS&quot; rel=&quot;noopener&quot;&gt;CORS&lt;/a&gt;
and use strict MIME-type checking.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;import-assertions-whats-with-the-assert&quot;&gt;Import Assertions (what&#39;s with the &#39;&lt;code&gt;assert&lt;/code&gt;&#39;?) &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/css-module-scripts/#import-assertions-whats-with-the-assert&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The &lt;code&gt;assert { type: &#39;css&#39; }&lt;/code&gt; part of the &lt;code&gt;import&lt;/code&gt; statement is an &lt;a href=&quot;https://v8.dev/features/import-assertions&quot; rel=&quot;noopener&quot;&gt;import
assertion&lt;/a&gt;. This is required; without it, the &lt;code&gt;import&lt;/code&gt; is
treated as a normal JavaScript module import, and will fail if the imported file has a
non-JavaScript MIME type.&lt;/p&gt;
&lt;div&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; sheet &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;./styles.css&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Failed to load module script:&lt;/span&gt;&lt;br /&gt;                                  &lt;span class=&quot;token comment&quot;&gt;// Expected a JavaScript module&lt;/span&gt;&lt;br /&gt;                                  &lt;span class=&quot;token comment&quot;&gt;// script but the server responded&lt;/span&gt;&lt;br /&gt;                                  &lt;span class=&quot;token comment&quot;&gt;// with a MIME type of &quot;text/css&quot;.&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;h2 id=&quot;dynamically-imported-stylesheets&quot;&gt;Dynamically imported stylesheets &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/css-module-scripts/#dynamically-imported-stylesheets&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;You can also import a CSS module using &lt;a href=&quot;https://v8.dev/features/dynamic-import#dynamic&quot; rel=&quot;noopener&quot;&gt;dynamic
import&lt;/a&gt;, with a new second parameter for the &lt;code&gt;type: &#39;css&#39;&lt;/code&gt; import assertion:&lt;/p&gt;
&lt;div&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; cssModule &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;./style.css&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token literal-property property&quot;&gt;assert&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;css&#39;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;document&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;adoptedStyleSheets &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;cssModule&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;default&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;aside class=&quot;aside flow bg-tertiary-box-bg color-tertiary-box-text&quot;&gt;&lt;p class=&quot;cluster &quot;&gt;&lt;span class=&quot;aside__icon box-block &quot;&gt;&lt;svg width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot; role=&quot;img&quot; aria-label=&quot;Lightbulb&quot; fill=&quot;currentColor&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot;&gt;   &lt;path d=&quot;M9 21c0 .55.45 1 1 1h4c.55 0 1-.45 1-1v-1H9v1zm3-19C8.14 2 5 5.14 5 9c0 2.38 1.19 4.47 3 5.74V17c0 .55.45 1 1 1h6c.55 0 1-.45 1-1v-2.26c1.81-1.27 3-3.36 3-5.74 0-3.86-3.14-7-7-7zm2.85 11.1l-.85.6V16h-4v-2.3l-.85-.6A4.997 4.997 0 017 9c0-2.76 2.24-5 5-5s5 2.24 5 5c0 1.63-.8 3.16-2.15 4.1z&quot;&gt;&lt;/path&gt; &lt;/svg&gt;&lt;/span&gt;&lt;strong&gt;Gotchas&lt;/strong&gt;&lt;/p&gt;&lt;div class=&quot; flow&quot;&gt; Note that it&#39;s &lt;code&gt;cssModule.default&lt;/code&gt; (not &lt;code&gt;cssModule&lt;/code&gt; itself) that is added to &lt;code&gt;adoptedStyleSheets&lt;/code&gt;. This is because the object returned from dynamic &lt;code&gt;import()&lt;/code&gt; is a module namespace object. The CSSStyleSheet is the default export of the module, so it&#39;s accessed at &lt;code&gt;cssModule.default&lt;/code&gt;. &lt;/div&gt;&lt;/aside&gt;
&lt;h2 id=&quot;import-rules-not-yet-allowed&quot;&gt;&lt;code&gt;@import&lt;/code&gt; rules not yet allowed &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/css-module-scripts/#import-rules-not-yet-allowed&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Currently CSS &lt;a href=&quot;https://developer.mozilla.org/docs/web/css/@import&quot; rel=&quot;noopener&quot;&gt;&lt;code&gt;@import&lt;/code&gt; rules&lt;/a&gt; don&#39;t work
in constructable stylesheets, including CSS module scripts. If &lt;code&gt;@import&lt;/code&gt; rules are present in a
constructable stylesheet, those rules will be ignored.&lt;/p&gt;
&lt;div&gt;&lt;pre class=&quot;language-css&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;/* atImported.css */&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token selector&quot;&gt;div&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token property&quot;&gt;background-color&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; blue&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;div&gt;&lt;pre class=&quot;language-css&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;/* styles.css */&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token atrule&quot;&gt;&lt;span class=&quot;token rule&quot;&gt;@import&lt;/span&gt; &lt;span class=&quot;token url&quot;&gt;&lt;span class=&quot;token function&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string url&quot;&gt;&#39;./atImported.css&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;/* Ignored in CSS module */&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token selector&quot;&gt;div&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token property&quot;&gt;border&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 1em solid green&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;div&gt;&lt;pre class=&quot;language-html&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;&amp;lt;!-- index.html --&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;script&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;module&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token script&quot;&gt;&lt;span class=&quot;token language-javascript&quot;&gt;&lt;br /&gt;    &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; styles &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;./styles.css&#39;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;assert&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;css&quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;    document&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;adoptedStyleSheets &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;styles&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;script&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;div&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;This div will have a green border but no background color.&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;div&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;p&gt;Support for &lt;code&gt;@import&lt;/code&gt; in CSS module scripts may be added to the specification. Track this
specification discussion in &lt;a href=&quot;https://github.com/WICG/webcomponents/issues/870&quot; rel=&quot;noopener&quot;&gt;the GitHub issue&lt;/a&gt;.&lt;/p&gt;
</content>
    <author>
      <name>Dan Clark</name>
    </author>
  </entry>
</feed>
