CSS Modules (The Native Ones)

Avatar of Chris Coyier
Chris Coyier on (Updated on )

They are actually called “CSS Module Scripts” and are a native browser feature, as opposed to the popular open-source project that essentially does scoped styles by creating unique class name identifiers in both HTML and CSS.

Native CSS Modules are a part of ES Modules (a lot like JSON modules we recently covered):

// Regular ES Modules
import React from "https://cdn.skypack.dev/[email protected]";

// Newfangled JSON Modules
import configData from './config-data.json' assert { type: 'json' };

// Newfangled CSS Modules
import styleSheet from "./styles.css" assert { type: "css" };

I first saw this from Justin’s tweet:

This is a Chrome-thing for now. Relevant links:

As I write, it only works in Chrome Canary with the Experimental Web Platform Features on. If your question is, When can I use this on production projects with a wide variety of users using whatever browser they want? I’d say: I have no idea. Probably years away. Maybe never. But it’s still interesting to check out. Maybe support will move fast. Maybe you’ll work on an Electron project or something where you can count on specific browser features.

This looks like an extension of Constructable Stylesheets, which are also Chrome-only, so browsers that are “behind” on this would have to start there.

I gave Justin’s idea a spin here:

If I log what I get back from the CSS Modules import, it’s a CSSStyleSheet:

Showing a styles tree with nodes for CSS rules, media, rules, and prototype.

If you’re going to actually use the styles… that’s on you. Justin’s idea basically applies the style as a one-liner because it just so happens that lit-html supports CSSStyleSheet (those docs don’t make that clear, but I imagine they will at some point). For native web components, it’s not much different: you import it, get the CSSStyleSheet, then apply it to the web component like:

this.shadowRoot.adoptedStyleSheets = [myCSSStyleSheet];

I would think the point of all this is:

  • we needed a way to import a stylesheet in JavaScript and this is basically the first really clear crack at it that I’m aware of,
  • now we have programatic access to manipulate the CSS before using it, if we wanted, and
  • it looks particularly nice for Web Components usage, but it’s generic. Do whatever you want with the stylesheet once you have it.