
CSS Modules : Styles scopés localement
Découvrez comment utiliser les CSS Modules en React pour créer des styles scopés localement, éviter les conflits de noms et améliorer la maintenabilité de vos composants.
La solution aux conflits de styles : Le scoping local
Comme nous l'avons vu précédemment, l'un des défis majeurs avec le CSS classique dans les applications basées sur des composants est la gestion de la portée globale des sélecteurs. Même en important un fichier CSS spécifiquement pour un composant, les classes définies à l'intérieur peuvent accidentellement affecter d'autres parties de l'application ou être écrasées par des styles définis ailleurs, surtout si les noms de classes ne sont pas uniques ou suffisamment spécifiques. Cela conduit souvent à des bugs difficiles à tracer et à une maintenance complexe.
Les CSS Modules offrent une solution élégante à ce problème en introduisant le concept de scope local par défaut pour vos styles. Au lieu que vos classes CSS soient ajoutées à l'espace de noms global, les CSS Modules transforment vos noms de classes en identifiants uniques lors du processus de build. Chaque classe que vous définissez dans un fichier CSS Module est automatiquement rendue unique pour le composant qui l'importe.
Cette transformation est généralement gérée par les outils de build modernes comme Webpack (utilisé par Create React App) ou Vite. Pour indiquer qu'un fichier CSS doit être traité comme un module, il suffit de suivre une convention de nommage spécifique : le fichier doit se terminer par `.module.css` (ou `.module.scss`, `.module.less` si vous utilisez des préprocesseurs).
Mise en oeuvre pratique des CSS modules
L'utilisation des CSS Modules est relativement simple. Prenons un exemple avec un composant `Bouton`. Vous créeriez un fichier nommé `Bouton.module.css` à côté de votre fichier `Bouton.js`.
Dans votre fichier JavaScript (`Bouton.js`), vous importez le fichier `.module.css` non pas directement, mais comme un objet. Conventionnellement, cet objet est souvent nommé `styles`.
// Bouton.js
import React from 'react';
import styles from './Bouton.module.css'; // Importation du module CSS
function Bouton({ type, children }) {
// Accès aux classes via l'objet 'styles'
const classesBouton = `${styles.boutonBase} ${type === 'primaire' ? styles.primaire : styles.secondaire}`;
return (
);
}
export default Bouton;Le fichier `Bouton.module.css` contient vos définitions de classes CSS habituelles :
/* Bouton.module.css */
.boutonBase {
padding: 10px 20px;
border: none;
border-radius: 4px;
cursor: pointer;
font-size: 1rem;
}
.primaire {
background-color: blue;
color: white;
}
.secondaire {
background-color: grey;
color: black;
}Lors du build, l'outil va transformer les noms de classes. Par exemple, `styles.boutonBase` pourrait devenir quelque chose comme `Bouton_boutonBase__aBcDe`, et `styles.primaire` deviendrait `Bouton_primaire__fGhIj`. L'objet `styles` importé contiendra alors le mapping entre vos noms de classes originaux (`boutonBase`, `primaire`) et ces noms uniques générés. L'élément `
Les avantages principaux des CSS Modules sont : la garantie d'isolation des styles (pas de conflits globaux), la maintenabilité (les styles sont liés au composant) et la composabilité (vous pouvez facilement combiner plusieurs classes comme montré dans l'exemple avec la logique ternaire). C'est une approche très populaire dans l'écosystème React car elle offre un bon équilibre entre la familiarité du CSS et la sécurité du scoping local, sans nécessiter l'apprentissage d'une nouvelle syntaxe comme avec certaines solutions CSS-in-JS.