← Back to React Course | Chapter 11: Styling in React | Lesson 1 of 8

CSS Modules

CSS Modules are like giving every component its own private locker for styles, so its class names never accidentally clash with another component's locker.
Syntax
markup
/* Name.module.css */
.className { property: value; }

// Component.jsx
import styles from "./Name.module.css";

<div className={styles.className}>Content</div>

The Problem CSS Modules Solve

Regular CSS class names are global — a class called '.card' in one file can accidentally override or be overridden by a '.card' class defined elsewhere in a large app.

CSS Modules solve this by automatically making class names locally scoped to whichever component imports that stylesheet.

Note: This problem grows worse as an app and team scale — CSS Modules are especially valuable in larger codebases with many contributors.
Warning: This is purely a build-time naming trick — it doesn't change how CSS itself works, just how class names are generated and matched up.

Example: The Problem CSS Modules Solve

markup
// Run in your local React project (npm install required)
/* Card.module.css */
.card { border: 1px solid #ccc; padding: 16px; }

// Card.jsx
import styles from './Card.module.css';
function Card() {
  return <div className={styles.card}>Content</div>;
}

How the Import Becomes an Object

Importing a .module.css file doesn't give you the raw CSS text — the build tool transforms it into a JavaScript object where each key is one of your original class names, and each value is a unique, generated class name (like card_a1b2c) that won't collide with anything else in the app.

Note: Console.log the imported styles object during development to see exactly what generated class names it contains.
Warning: Referencing styles.someClassName for a class that doesn't exist in the CSS file returns undefined, silently applying no class at all.

Example: How the Import Becomes an Object

markup
// Run in your local React project (npm install required)
import styles from './Button.module.css';

function Button() {
  console.log(styles); // { button: "button_a3f9c" }
  return <button className={styles.button}>Click me</button>;
}

Combining Multiple Classes

When a component needs more than one CSS Modules class at once (like a base style plus a conditional variant), you combine the generated class name strings with template literals or a small helper, since JSX's className just wants one final string.

Note: Libraries like classnames or clsx make combining multiple conditional classes cleaner than manual string concatenation.
Warning: Concatenating class names with a plain '+' instead of a template literal or space-joining can accidentally merge two class names into one invalid string.

Example: Combining Multiple Classes

markup
// Run in your local React project (npm install required)
import styles from './Button.module.css';

function Button({ primary }) {
  const className = primary ? `${styles.button} ${styles.primary}` : styles.button;
  return <button className={className}>Click me</button>;
}
Related Topics
{# common_mistakes/chapter_summary/browser_support: on Hindi pages the view already swaps in the hi_ translation fields (or blanks these out if untranslated), so this renders correctly for both languages without a lang_code check here. #}
Common Mistakes
  1. Forgetting the import syntax is different — you import the CSS file as an object (import styles from './App.module.css'), not as a side-effect import.
  2. Using regular string class names instead of the generated styles.className property.
  3. Naming the file just 'App.css' instead of 'App.module.css' — the '.module.css' suffix is what triggers CSS Modules processing in most build tools.
Chapter Summary
  • CSS Modules scope class names locally to the component that imports them, avoiding global naming collisions.
  • A file named Component.module.css is processed specially by the build tool (Vite, webpack, etc.).
  • Imported styles become a JS object mapping your original class names to generated, unique ones.
  • This is a build-tool feature, not a runtime library — no CDN equivalent exists for this preview sandbox.
Browser Support

Build-tool feature (Vite/webpack/Create React App all support it); no specific React version requirement.

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.