React CSS Modules
Scoped and modular CSS for React components
📦 What are CSS Modules?
CSS Modules are CSS files where class names are scoped locally by default. This prevents style conflicts and makes your components more maintainable by ensuring styles don't leak between components.
import styles from './Button.module.css';
Understanding CSS Modules
CSS Modules automatically generate unique class names for your styles, preventing naming conflicts across components. Each component can have its own styles without worrying about affecting other parts of your application. This approach combines the simplicity of CSS with the power of component-based architecture.
Scoped Styles
Styles are local to components
No Conflicts
Unique class names generated
Regular CSS
Write normal CSS syntax
Reusable
Import and use anywhere
🔹 Creating a CSS Module
CSS Module files use the .module.css extension:
🔸 Button.module.css
.button {
padding: 12px 24px;
font-size: 16px;
border: none;
border-radius: 6px;
cursor: pointer;
transition: all 0.3s;
}
.primary {
background-color: #007bff;
color: white;
}
.primary:hover {
background-color: #0056b3;
}
.secondary {
background-color: #6c757d;
color: white;
}
.secondary:hover {
background-color: #545b62;
}
🔸 Button.jsx
import styles from './Button.module.css';
function Button({ type = 'primary', children }) {
return (
<button className={`${styles.button} ${styles[type]}`}>
{children}
</button>
);
}
// Usage
<Button type="primary">Primary Button</Button>
<Button type="secondary">Secondary Button</Button>
Output:
🔹 Multiple Classes
Combine multiple CSS Module classes:
🔸 Card.module.css
.card {
background: white;
border-radius: 8px;
padding: 20px;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}
.title {
font-size: 24px;
color: #333;
margin-bottom: 10px;
}
.content {
color: #666;
line-height: 1.6;
}
.highlighted {
border-left: 4px solid #007bff;
background-color: #f8f9fa;
}
🔸 Card.jsx
import styles from './Card.module.css';
function Card({ title, content, highlighted }) {
const cardClass = highlighted
? `${styles.card} ${styles.highlighted}`
: styles.card;
return (
<div className={cardClass}>
<h3 className={styles.title}>{title}</h3>
<p className={styles.content}>{content}</p>
</div>
);
}
Output:
Card Title
This is a highlighted card with CSS Modules.
🔹 Composition
Reuse styles using the composes keyword:
🔸 Alert.module.css
.alert {
padding: 15px;
border-radius: 4px;
margin-bottom: 10px;
font-weight: 500;
}
.success {
composes: alert;
background-color: #d4edda;
color: #155724;
border: 1px solid #c3e6cb;
}
.error {
composes: alert;
background-color: #f8d7da;
color: #721c24;
border: 1px solid #f5c6cb;
}
.warning {
composes: alert;
background-color: #fff3cd;
color: #856404;
border: 1px solid #ffeaa7;
}
🔸 Alert.jsx
import styles from './Alert.module.css';
function Alert({ type, message }) {
return (
<div className={styles[type]}>
{message}
</div>
);
}
// Usage
<Alert type="success" message="Success! Your changes were saved." />
<Alert type="error" message="Error! Something went wrong." />
<Alert type="warning" message="Warning! Please check your input." />
🔹 Global Styles in Modules
Use :global for styles that should not be scoped:
/* Component.module.css */
.container {
padding: 20px;
}
/* This class will be global */
:global(.global-class) {
color: red;
}
/* Mix local and global */
.container :global(.global-text) {
font-weight: bold;
}
CSS Modules Benefits:
- No naming conflicts: Unique class names automatically generated
- Component-scoped: Styles only apply to their component
- Easy to maintain: Styles live next to components
- Standard CSS: Use regular CSS syntax you already know
- Better performance: Only loads styles for used components
🔹 Naming Convention
Follow these naming patterns for CSS Modules:
- File naming: ComponentName.module.css
- Class naming: Use camelCase or kebab-case
- Import naming: import styles from './Component.module.css'
- Usage: className={styles.className}
// Good practices
import styles from './UserProfile.module.css';
<div className={styles.profileCard}>
<h2 className={styles.userName}>John Doe</h2>
<p className={styles.userBio}>Developer</p>
</div>