CSS Approaches in React
React supports multiple ways to style components. The most common approaches are CSS Modules (scoped CSS), inline styles, and CSS-in-JS libraries. Each has trade-offs in terms of scoping, maintainability, and developer experience.
CSS Modules are the most popular built-in solution — they automatically scope class names to the component, preventing style conflicts.
Example
/* Button.module.css */
.button {
padding: 10px 20px;
border: none;
border-radius: 8px;
cursor: pointer;
}
.primary {
background: #d1039e;
color: white;
}
.secondary {
background: #e0e0e0;
color: #333;
} - CSS Modules — Scoped CSS with .module.css files (built-in with Vite/CRA)
- Inline Styles — style={{ color: 'red' }} for dynamic styles
- Tailwind CSS — Utility-first CSS framework, very popular with React
- Styled Components — CSS-in-JS library using tagged template literals
- Plain CSS — Regular CSS files, simplest but no scoping
Notes
- CSS Modules are recommended for most projects. They provide scoping without adding a library dependency. Tailwind CSS is a great choice if you prefer utility classes.
Using CSS Modules
Import CSS Module files as an object, then use the class names as properties. Vite and CRA automatically process files ending in .module.css.
Example
import styles from './Button.module.css';
function Button({ variant = 'primary', children }) {
return (
<button className={`${styles.button} ${styles[variant]}`}>
{children}
</button>
);
}
// Inline styles for dynamic values
function ProgressBar({ percent }) {
return (
<div style={{
width: '100%',
height: '8px',
backgroundColor: '#e0e0e0',
borderRadius: '4px'
}}>
<div style={{
width: `${percent}%`,
height: '100%',
backgroundColor: '#d1039e',
borderRadius: '4px',
transition: 'width 0.3s ease'
}} />
</div>
);
} Notes
- Inline styles use camelCase properties (backgroundColor, not background-color) and values are strings or numbers.
