Les composants React se stylisent avec du CSS classique. Donnez une classe aux éléments avec la prop className et écrivez les règles dans une feuille de style, utilisez la prop style pour les valeurs qui viennent du JavaScript, et passez aux CSS Modules ou à Tailwind quand un projet grandit. L'exemple ci-dessous définit son CSS dans un élément <style> pour pouvoir s'exécuter sur cette page ; dans un projet, il serait dans un fichier .css.
Remplacez #2563eb par #16a34a dans la règle .btn et le bouton devient vert. Tout ce que vous savez du CSS s'applique : sélecteurs, media queries, états au survol, animations.
className, pas class
Le JSX se compile en JavaScript, où class est un mot réservé, donc React utilise className, le nom que le DOM lui-même donne à cette propriété (element.className). Le navigateur reçoit quand même un attribut class ordinaire. Le même renommage s'applique à htmlFor au lieu de for sur les labels. React 19 accepte class avec un avertissement en développement, mais className est le nom correct et celui qu'utilisent toutes les bases de code.
className prend une chaîne, plusieurs classes sont donc séparées par des espaces : className="btn btn-primary". Comme la valeur est du JavaScript, elle peut être calculée.
Classes conditionnelles
Pour n'ajouter une classe que dans certains cas, construisez la chaîne avec un ternaire ou un littéral de gabarit. Une barre d'onglets qui met en valeur l'onglet sélectionné est le cas classique.
Cliquez sur Lessons et le soulignement se déplace, car seule la chaîne de ce bouton contient maintenant active. Reviews reçoit la classe disabled et l'attribut disabled, il est donc gris et ignore les clics. Le littéral de gabarit laisse des espaces en trop quand une condition est fausse, ce que les navigateurs ignorent. Quand un composant a beaucoup de classes conditionnelles, un tableau est plus propre :
const classes = ['tab', isActive && 'active', isDisabled && 'disabled']
.filter(Boolean)
.join(' ');
Beaucoup de projets utilisent le petit paquet clsx pour la même tâche : clsx('tab', { active: isActive, disabled: isDisabled }).
La prop style
La prop style prend un objet JavaScript, pas une chaîne. C'est pourquoi elle a des doubles accolades : la paire extérieure ouvre une expression JavaScript, la paire intérieure est le littéral d'objet. Les noms de propriétés sont en camelCase (backgroundColor, fontSize, borderRadius), et les valeurs sont des chaînes ou des nombres. Un nombre sur une propriété de longueur devient des pixels, donc padding: 12 signifie 12px.
Les styles inline sont utiles quand une valeur est calculée au moment du rendu, comme la largeur d'une barre de progression.
Cliquez sur Add 10% jusqu'à remplir la barre et elle devient verte. Notez width: percent + '%' : un nombre seul signifierait des pixels, donc les unités autres que px vont dans une chaîne. Les propriétés sans unité restent de simples nombres, comme opacity: 0.8, zIndex: 2, flexGrow: 1 et lineHeight: 1.5 (qui est un multiplicateur, pas des pixels).
Les styles inline ont des limites. Ils ne peuvent pas exprimer :hover, :focus, les media queries ni les animations keyframes, et chaque élément porte sa propre copie des règles. Utilisez-les pour les valeurs dynamiques et gardez le reste en CSS.
Variables CSS à partir des props
Un bon compromis consiste à définir une propriété personnalisée CSS dans style et à l'utiliser depuis votre feuille de style. Les règles restent en CSS, états au survol compris, et seule la valeur vient du JavaScript.
Choisissez une nouvelle couleur et les deux boutons la suivent, et le remplissage au survol fonctionne toujours car c'est du CSS classique. Les noms de propriétés personnalisées gardent leurs tirets dans l'objet style, ils vont donc entre guillemets : { '--accent': accent }.
Fichiers CSS
Dans un vrai projet, vous écrivez les styles dans des fichiers .css et les importez depuis le composant qui en a besoin. Avec Vite, l'import suffit : l'outil de build voit import './Button.css', ajoute la feuille de style à la page pendant le développement, et l'intègre dans un fichier CSS pour la production. Il n'y a rien à utiliser en retour ; l'import n'existe que pour son effet de bord.
// Button.jsx
import './Button.css';
export default function Button({ children }) {
return <button className="button">{children}</button>;
}
/* Button.css */
.button {
background: #2563eb;
color: white;
border-radius: 6px;
}
Le problème, c'est que chaque feuille de style importée est globale. Une règle .button dans Button.css stylise tous les éléments qui ont cette classe, partout dans l'application, et deux fichiers qui définissent tous deux .title s'écrasent l'un l'autre. Les équipes gèrent cela avec des conventions de nommage comme BEM (.card__title), ou avec les CSS Modules.
CSS Modules
Un fichier qui se termine par .module.css est un CSS Module. L'importer vous donne un objet qui associe chaque nom de classe écrit à un nom unique généré, pour qu'une classe ne s'applique que là où vous l'utilisez. Vite et Next.js le prennent en charge sans configuration.
// Card.jsx
import styles from './Card.module.css';
export default function Card({ title, children, featured }) {
return (
<section className={featured ? `${styles.card} ${styles.featured}` : styles.card}>
<h3 className={styles.title}>{title}</h3>
{children}
</section>
);
}
/* Card.module.css */
.card { border: 1px solid #ddd; border-radius: 10px; padding: 16px; }
.featured { border-color: #2563eb; }
.title { margin: 0; }
Dans le navigateur, la classe devient quelque chose comme _card_1x2ab_1. Un autre composant peut définir son propre .title et les deux n'entrent jamais en conflit. Vous écrivez du CSS normal, règles de survol et media queries comprises, c'est pourquoi les CSS Modules sont un choix par défaut courant pour styliser les composants.
Tailwind CSS avec React
Tailwind adopte une autre approche : au lieu d'écrire des règles, vous combinez de petites classes utilitaires directement dans className. px-4 définit le padding horizontal, rounded-lg arrondit les coins, hover:bg-blue-700 change le fond au survol. Tailwind analyse vos fichiers et ne génère du CSS que pour les classes que vous utilisez.
L'installer dans une application React avec Vite (Tailwind v4) prend trois étapes :
npm install tailwindcss @tailwindcss/vite
// vite.config.js
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import tailwindcss from '@tailwindcss/vite';
export default defineConfig({
plugins: [react(), tailwindcss()],
});
/* src/index.css, imported from main.jsx */
@import "tailwindcss";
Stylisez ensuite les composants avec des classes :
function UpgradeCard({ active }) {
return (
<div className="max-w-xs rounded-xl border border-gray-200 p-4">
<h3 className="mb-2 text-lg font-semibold">Pro plan</h3>
<button
className={`rounded-md px-4 py-2 text-white ${active ? 'bg-green-600' : 'bg-blue-600 hover:bg-blue-700'}`}
>
{active ? 'Active' : 'Upgrade'}
</button>
</div>
);
}
Tailwind n'est pas disponible dans les éditeurs de cette page, il est donc montré en code statique. Les classes conditionnelles fonctionnent exactement comme dans l'exemple des onglets ci-dessus, mais écrivez chaque nom de classe en entier : Tailwind trouve les classes en analysant le texte de vos sources, donc un nom assemblé à l'exécution comme `bg-${color}-600` n'est jamais généré.
Quand utiliser quoi
- Les fichiers CSS classiques conviennent aux petites applications et aux styles globaux (reset, polices, mise en page). Méfiez-vous des conflits de noms de classes quand l'application grandit.
- Les CSS Modules conviennent à la plupart des styles de composants : du CSS normal, isolé automatiquement, sans bibliothèque supplémentaire.
- Tailwind convient aux équipes qui préfèrent styliser dans le balisage et veulent une échelle commune pour les espacements et les couleurs.
- La prop
stylesert aux valeurs calculées au moment du rendu : une largeur, une position, la couleur choisie par un utilisateur. Associez-la aux variables CSS pour garder les règles de survol et les media queries en CSS.
Vous pouvez les combiner. Une application typique a une feuille de style globale, des CSS Modules ou Tailwind pour les composants, et quelques styles inline pour les valeurs dynamiques. Les bibliothèques CSS-in-JS comme styled-components et Emotion sont une autre option que vous croiserez dans d'anciennes bases de code. La page sur l'installation de React montre comment démarrer un projet Vite où tout cela fonctionne.
Questions fréquentes
Pourquoi React utilise-t-il className au lieu de class ?
Le JSX se compile en JavaScript, où class est un mot réservé. React utilise le nom de la propriété DOM, className, qui est aussi le nom de element.className en JavaScript classique. Cela devient quand même un attribut class normal dans le HTML.
Comment écrire des styles inline en React ?
Passez un objet à la prop style, avec des noms de propriétés en camelCase : style={{ backgroundColor: 'teal', fontSize: 18 }}. Les accolades extérieures ouvrent une expression JavaScript et les accolades intérieures sont l'objet. Les nombres deviennent des pixels pour les propriétés qui prennent une longueur.
Comment ajouter une classe sous condition en React ?
Construisez la chaîne en JavaScript : className={isActive ? 'tab active' : 'tab'} ou un littéral de gabarit comme className={`tab ${isActive ? 'active' : ''}`}. Avec beaucoup de conditions, un petit utilitaire comme le paquet clsx garde le code lisible.
Les fichiers CSS sont-ils globaux en React ?
Oui. import './App.css' ajoute la feuille de style à toute la page, ses noms de classes peuvent donc entrer en conflit avec ceux d'autres fichiers. Les CSS Modules (App.module.css) renomment chaque classe avec un nom unique pour qu'elle ne s'applique que là où vous l'importez.
Comment utiliser Tailwind avec React ?
Dans un projet Vite, installez tailwindcss et @tailwindcss/vite, ajoutez le plugin à vite.config.js, et placez @import "tailwindcss"; en haut de votre fichier CSS principal. Écrivez ensuite des classes utilitaires dans className, comme className="px-4 py-2 rounded bg-blue-600 text-white".