Menu

CSS in React: className, stili inline, CSS Modules, Tailwind

Dai stile ai componenti React con className e normale CSS, con la prop style per i valori calcolati in JavaScript, con i CSS Modules per nomi di classe isolati, o con le classi di utilità di Tailwind. Impara ogni approccio, le classi condizionali e quando usare quale.

Questa pagina include editor eseguibili: modifica, esegui e vedi subito l'output.

Ai componenti React si dà stile con il normale CSS. Assegna una classe agli elementi con la prop className e scrivi le regole in un foglio di stile, usa la prop style per i valori che arrivano da JavaScript, e passa ai CSS Modules o a Tailwind quando un progetto cresce. L'esempio qui sotto definisce il suo CSS in un elemento <style> così da poter girare in questa pagina; in un progetto starebbe in un file .css.

Cambia #2563eb in #16a34a nella regola .btn e il pulsante diventa verde. Tutto ciò che sai del CSS vale anche qui: selettori, media query, stati hover, animazioni.

className, non class

JSX viene compilato in JavaScript, dove class è una parola riservata, quindi React usa className, il nome che il DOM stesso usa per quella proprietà (element.className). Il browser riceve comunque un normale attributo class. La stessa sostituzione vale per htmlFor al posto di for sulle etichette. React 19 accetta class con un avviso in sviluppo, ma className è il nome corretto e quello che usano tutte le codebase.

className accetta una stringa, quindi più classi si separano con uno spazio: className="btn btn-primary". Poiché il valore è JavaScript, può essere calcolato.

Classi condizionali

Per aggiungere una classe solo in alcuni casi, costruisci la stringa con un ternario o un template literal. Una barra di schede che evidenzia la scheda selezionata è il caso classico.

Clicca Lessons e la sottolineatura si sposta, perché ora solo la stringa di quel pulsante contiene active. Reviews riceve la classe disabled e l'attributo disabled, quindi è grigio e ignora i clic. Il template literal lascia spazi in più quando una condizione è falsa, e i browser li ignorano. Quando un componente ha molte classi condizionali, un array è più ordinato:

const classes = ['tab', isActive && 'active', isDisabled && 'disabled']
    .filter(Boolean)
    .join(' ');

Molti progetti usano il minuscolo pacchetto clsx per lo stesso scopo: clsx('tab', { active: isActive, disabled: isDisabled }).

La prop style

La prop style accetta un oggetto JavaScript, non una stringa. Per questo ha le doppie graffe: la coppia esterna apre un'espressione JavaScript, quella interna è il letterale dell'oggetto. I nomi delle proprietà sono in camelCase (backgroundColor, fontSize, borderRadius), e i valori sono stringhe o numeri. Un numero su una proprietà di lunghezza diventa pixel, quindi padding: 12 significa 12px.

Gli stili inline danno il meglio quando un valore viene calcolato al momento del rendering, come la larghezza di una barra di avanzamento.

Clicca Add 10% finché la barra si riempie e diventa verde. Nota width: percent + '%': un numero da solo significherebbe pixel, quindi le unità diverse da px vanno in una stringa. Le proprietà senza unità restano semplici numeri, come opacity: 0.8, zIndex: 2, flexGrow: 1 e lineHeight: 1.5 (che è un moltiplicatore, non pixel).

Gli stili inline hanno dei limiti. Non possono esprimere :hover, :focus, media query o animazioni keyframe, e ogni elemento porta con sé la propria copia delle regole. Usali per i valori dinamici e tieni il resto nel CSS.

Variabili CSS dalle props

Una buona via di mezzo è impostare una custom property CSS in style e usarla dal foglio di stile. Le regole restano nel CSS, stati hover inclusi, e solo il valore arriva da JavaScript.

Scegli un nuovo colore ed entrambi i pulsanti lo seguono, e il riempimento al passaggio del mouse funziona ancora perché è semplice CSS. I nomi delle custom property mantengono i trattini nell'oggetto style, quindi vanno tra virgolette: { '--accent': accent }.

File CSS

In un progetto reale scrivi gli stili in file .css e li importi dal componente che ne ha bisogno. Con Vite basta l'import: lo strumento di build vede import './Button.css', aggiunge il foglio di stile alla pagina durante lo sviluppo e lo include in un file CSS per la produzione. Non c'è alcun export da usare; l'import esiste solo per il suo effetto collaterale.

// 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;
}

Il problema è che ogni foglio di stile importato è globale. Una regola .button in Button.css dà stile a ogni elemento con quella classe, ovunque nell'app, e due file che definiscono entrambi .title si sovrascrivono a vicenda. I team lo gestiscono con convenzioni di nomi come BEM (.card__title), oppure con i CSS Modules.

CSS Modules

Un file che termina in .module.css è un CSS Module. Importarlo ti dà un oggetto che associa ogni nome di classe che hai scritto a un nome generato univoco, quindi una classe può applicarsi solo dove la usi. Vite e Next.js lo supportano senza alcuna configurazione.

// 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; }

Nel browser la classe diventa qualcosa come _card_1x2ab_1. Un altro componente può definire il proprio .title e i due non entrano mai in conflitto. Scrivi CSS normale, regole hover e media query incluse, ed è per questo che i CSS Modules sono una scelta predefinita comune per gli stili dei componenti.

Tailwind CSS con React

Tailwind ha un approccio diverso: invece di scrivere regole, componi piccole classi di utilità direttamente in className. px-4 imposta il padding orizzontale, rounded-lg arrotonda gli angoli, hover:bg-blue-700 cambia lo sfondo al passaggio del mouse. Tailwind analizza i tuoi file e genera CSS solo per le classi che usi.

Configurarlo in un'app React con Vite (Tailwind v4) richiede tre passaggi:

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";

Poi dai stile ai componenti con le classi:

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 non è disponibile negli editor di questa pagina, quindi è mostrato come codice statico. Le classi condizionali funzionano esattamente come nell'esempio delle schede qui sopra, ma scrivi ogni nome di classe per intero: Tailwind trova le classi analizzando il testo del tuo codice sorgente, quindi un nome assemblato a runtime come `bg-${color}-600` non viene mai generato.

Quando usare quale

  • I semplici file CSS vanno bene per app piccole e stili globali (reset, font, layout della pagina). Fai attenzione ai conflitti tra nomi di classe man mano che l'app cresce.
  • I CSS Modules vanno bene per la maggior parte degli stili dei componenti: CSS normale, isolato automaticamente, nessuna libreria in più.
  • Tailwind va bene per i team che preferiscono dare stile nel markup e vogliono una scala di design condivisa per spaziature e colori.
  • La prop style serve per i valori calcolati al momento del rendering: una larghezza, una posizione, il colore scelto da un utente. Abbinala alle variabili CSS per tenere le regole hover e media nel CSS.

Puoi combinarli. Un'app tipica ha un foglio di stile globale, CSS Modules o Tailwind per i componenti e qualche stile inline per i valori dinamici. Le librerie CSS in JS come styled-components ed Emotion sono un'altra opzione che incontrerai nelle codebase più vecchie. La pagina su come installare React mostra come avviare un progetto Vite in cui funzionano tutti questi approcci.

Domande frequenti

Perché React usa className invece di class?

JSX viene compilato in JavaScript, e lì class è una parola riservata. React usa il nome della proprietà DOM, className, che è anche il nome di element.className in JavaScript semplice. Nell'HTML diventa comunque un normale attributo class.

Come scrivo stili inline in React?

Passa un oggetto alla prop style, con nomi di proprietà in camelCase: style={{ backgroundColor: 'teal', fontSize: 18 }}. Le graffe esterne aprono un'espressione JavaScript e quelle interne sono l'oggetto. I numeri diventano pixel per le proprietà che accettano una lunghezza.

Come aggiungo una classe in modo condizionale in React?

Costruisci la stringa in JavaScript: className={isActive ? 'tab active' : 'tab'} oppure un template literal come className={`tab ${isActive ? 'active' : ''}`}. Con molte condizioni, un piccolo helper come il pacchetto clsx mantiene il codice leggibile.

I file CSS in React sono globali?

Sì. import './App.css' aggiunge il foglio di stile all'intera pagina, quindi i suoi nomi di classe possono entrare in conflitto con altri file. I CSS Modules (App.module.css) rinominano ogni classe con un nome univoco, così si applica solo dove la importi.

Come uso Tailwind con React?

In un progetto Vite, installa tailwindcss e @tailwindcss/vite, aggiungi il plugin a vite.config.js e metti @import "tailwindcss"; in cima al tuo file CSS principale. Poi scrivi le classi di utilità in className, come className="px-4 py-2 rounded bg-blue-600 text-white".

Illustrazione dei linguaggi di programmazione di Coddy

Impara a programmare con Coddy

INIZIA