On This Page

  1. Installation
  2. Usage
  3. Types

CSS Modules ™️

A plugin for authoring CSS Modules ™️, that is a modest implementation of the specification. See the plugin's README for complete usage information.

This is NOT to be confused with CSS Module Scripts, which Greenwood already supports.

Installation

You can use your favorite JavaScript package manager to install this package.

npm i -D @greenwood/plugin-css-modules
yarn add @greenwood/plugin-css-modules --dev
pnpm add -D @greenwood/plugin-css-modules

Then add this plugin to your greenwood.config.js.

import { greenwoodPluginCssModules } from "@greenwood/plugin-css-modules";

export default {
  plugins: [greenwoodPluginCssModules()],
};

Usage

Now you can create a CSS file that ends in .module.css:

.container {
  display: flex;
  justify-content: space-between;
}

.navBarMenu {
  border: 1px solid #020202;
}

.navBarMenuItem {
  & a {
    text-decoration: none;
    color: #020202;
  }
}

@media screen and (min-width: 768px) {
  .container {
    padding: 10px 20px;
  }
}

And reference that in your (Light DOM) HTML based Web Component:

import styles from "./header.module.css";

export default class Header extends HTMLElement {
  connectedCallback() {
    this.innerHTML = `
      <header class="${styles.container}">
        <ul class="${styles.navBarMenu}">
          <li class="${styles.navBarMenuItem}">
            <a href="/about/" title="Documentation">About</a>
          </li>
          <li class="${styles.navBarMenuItem}">
            <a href="/contact/" title="Guides">Contact</a>
          </li>
        </ul>
      </header>
    `;
  }
}

customElements.define("app-header", Header);

From there, Greenwood will scope your CSS class names by prefixing them with the filename and a hash of the contents, inline that into a <style> tag in the HTML, and then strip the reference to the module.css file from your JavaScript file.

Types

Types should automatically be inferred through this package's exports map, but can be referenced explicitly in both JavaScript (JSDoc) and TypeScript files if needed.

/** @type {import('@greenwood/plugin-css-modules').CssModulesPlugin} */
import type { CssModulesPlugin } from '@greenwood/plugin-css-modules';

To support typing of .module.css imports, you can add this type definition to your project:

declare module "*.module.css" {
  const styles: { [className: string]: string };
  export default styles;
}