CSS Modules for Scoped Component Styling0%

CSS Modules for Scoped Component Styling

Beginner12 min read•Updated: Jul 11, 2026
Study MaterialsCheatsheet

CSS Modules for Scoped Component Styling

1. The Need for Scoped CSS

As applications grow to hundreds of components, global CSS namespace collisions become inevitable. You want the flexibility of writing pure, clean CSS with full support for pseudo-classes, media queries, and animations—without the fear that your classes will accidentally leak or clash with other components.

CSS Modules solve this problem elegantly. A CSS Module is a CSS file where all class names and animation names are scoped locally to the component by default.

Vite supports CSS Modules out of the box with zero configuration required!

2. Naming Convention: [name].module.css

To inform Vite and your bundler that a stylesheet is a CSS Module, simply name the file with the .module.css extension:

Output
src/components/
├── Badge.jsx
└── Badge.module.css # Identified by Vite as a CSS Module

3. How CSS Modules Work

In your CSS Module, write standard, clean CSS classes:

CSS
/* src/components/Badge.module.css */
.badge {
display: inline-flex;
align-items: center;
padding: 4px 10px;
border-radius: 9999px;
font-size: 12px;
font-weight: 600;
}
 
.success {
background-color: #dcfce7;
color: #15803d;
}
 
.warning {
background-color: #fef9c3;
color: #a16207;
}

In your React component, import the styles as an object:

JSX
// src/components/Badge.jsx
import React from 'react';
import styles from './Badge.module.css'; // Imports object mapping class names
 
export default function Badge({ type = 'success', children }) {
// Access scoped classes via styles object properties
return (
<span className={`${styles.badge} ${styles[type]}`}>
{children}
</span>
);
}

4. Under the Hood: Class Name Hashing

When Vite processes Badge.module.css, it automatically transforms every class name into a unique, hashed string:

Output
Source Class: .badge
Rendered HTML: <span class="_badge_1s8fg_1 _success_1s8fg_15">

Because the compiled class names include unique hashes derived from the file path and component name, it is mathematically impossible for .badge in Badge.module.css to collide with .badge in UserCard.module.css!


Interactive Quiz

Practice Quiz

Question 1
What file naming convention is required for Vite to automatically treat a stylesheet as a CSS Module?
Question 2
How are CSS classes referenced in JSX when using CSS Modules?
Question 3
How do CSS Modules prevent class name conflicts between different components?
Question 4
Can you use pseudo-classes like :hover and media queries inside CSS Modules?
Question 5
How do you access a CSS Module class that contains a hyphen (e.g., .badge-primary) in JSX?
Next Lesson

Utility-First Styling with Tailwind CSS in React

Continue learning with hands-on practice, examples, and exercises in the upcoming topic.

Practice Quiz

Test your understanding of this lesson with 5 questions. Each question has one correct answer.

PrevNext