CSS Modules

Overview

CSS Modules provides a way to scope CSS rules with selectors that are class names to a component in a web framework. It does not support scoping CSS rules with selectors that only target specific HTML elements.

Web frameworks that have built-in support for CSS scoping such as Svelte and Vue have no need for CSS Modules. CSS Modules are mostly commonly used in React and web frameworks built-in on React such as Next.js.

Installing

Next.js projects and React projects created with create-react-app automatically include support for CSS Modules.

React projects created in other ways may require configuration. Options include:

Component Styles

To define CSS rules that should be scoped to a component, create a file whose name matches that of the source file that defines the component. The recommended file extension is .module.css.

CSS Module source files use standard CSS syntax, but support a small number of extensions including:

It is recommended to use camelCase names for CSS classes define in CSS Modules source files. The reason is that these become properties on an exported JavaScript object. Referencing properties with snake_case or kebab-case names is somewhat tedious because they must be inside quotes that are inside square brackets. For example, writing styles.myClassName is easier than writing styles['my-class-name'].

The following file, MyComponent.module.css, defines styles that will be scoped to the component MyComponent.

.title {
color: purple;
font-size: 1.5rem;
font-weight: bold;
}

.myComponent p {
color: blue;
}

The following file, MyComponent.tsx, defines a component that uses the styles defined above.

import React from 'react';

// The name "styles" here can be changed to anything,
// but this name is commonly used.
import styles from './MyComponent.module.css';

type Props = {
title: string,
content: string
};

export default function MyComponent({title, content}: Props) {
return (
<section className={styles.myComponent}>
<div className={styles.title}>{title}</div>
<p>{content}</p>
</section>
);
}

This component can be used as follows:

<MyComponent title="My Story" content="Once upon a time ..." />

CSS Modules demo

The styles object imported above will have a value similar to the following:

MyComponent.tsx x: styles = {
myClass: 'MyComponent_myClass__ac2E0',
myComponent: 'MyComponent_myComponent__SsuQ7',
__checksum: '94c8de6fb949'
}

The hash values at the ends of the generated class names are the key to scoping styles to a component. By default, they only change with the file name changes, not when the CSS rules change. There are several ways to change the strategy for generating these hash values if desired, including specifying a localIdentHashFunction.