Tailwind CSS
Tailwind CSS verfolgt einen völlig anderen Ansatz: Statt eigene CSS-Klassen zu schreiben, kombinierst du vorgefertigte Utility-Klassen direkt im className. Jede Klasse macht genau eine Sache — p-4 setzt Padding, text-blue-600 färbt Text blau, rounded-lg rundet Ecken ab.
Installation & Konfiguration
Abschnitt betitelt „Installation & Konfiguration“npm install tailwindcss @tailwindcss/viteFüge das Vite-Plugin hinzu:
import { defineConfig } from 'vite';import react from '@vitejs/plugin-react';import tailwindcss from '@tailwindcss/vite';
export default defineConfig({ plugins: [ react(), tailwindcss(), ],});Importiere Tailwind in deiner Haupt-CSS-Datei:
@import "tailwindcss";Verwendung
Abschnitt betitelt „Verwendung“Bei Tailwind gibt es keine separaten CSS-Dateien. Alle Styles stehen direkt im JSX als Utility-Klassen.
Button.jsx
Abschnitt betitelt „Button.jsx“function Button({ variant = "default", children }) { const baseClasses = "px-4 py-2 rounded-md text-sm font-medium cursor-pointer";
const variantClasses = variant === "primary" ? "bg-blue-600 text-white border border-blue-600 hover:bg-blue-700" : "bg-white text-gray-700 border border-gray-300 hover:bg-gray-100";
return ( <button className={`${baseClasses} ${variantClasses}`}> {children} </button> );}
export default Button;Die Klassen lesen sich wie eine Beschreibung: px-4 = Padding horizontal 1rem, py-2 = Padding vertikal 0.5rem, rounded-md = mittlere Eckenrundung, bg-blue-600 = Hintergrundfarbe Blau Stufe 600.
CardTitle.jsx
Abschnitt betitelt „CardTitle.jsx“function CardTitle({ children }) { return ( <header className="px-5 py-4 border-b border-gray-200 bg-gray-50"> <h2 className="m-0 text-lg font-semibold">{children}</h2> </header> );}
export default CardTitle;CardContent.jsx
Abschnitt betitelt „CardContent.jsx“function CardContent({ children }) { return ( <div className="p-5">{children}</div> );}
export default CardContent;Card.jsx
Abschnitt betitelt „Card.jsx“function Card({ children }) { return ( <article className="border border-gray-200 rounded-lg overflow-hidden"> {children} </article> );}
export default Card;App.jsx
Abschnitt betitelt „App.jsx“import Card from "./Card";import CardTitle from "./CardTitle";import CardContent from "./CardContent";import Button from "./Button";
function App() { return ( <div className="max-w-xl mx-auto p-5 font-sans"> <header className="flex items-center gap-3 mb-6"> <img src="https://react.dev/images/brand/logo_light.svg" alt="React Logo" width="40" height="40" /> <h1 className="m-0 text-2xl font-bold">CSS mit React</h1> </header>
<main> <Card> <CardTitle>Willkommen</CardTitle> <CardContent> <p> Diese kleine App zeigt, wie du React-Komponenten mit verschiedenen CSS-Ansätzen stylen kannst. Die Struktur bleibt immer gleich — nur das Styling ändert sich. </p> <div className="flex gap-2 mt-4"> <Button>Zurück</Button> <Button variant="primary">Weiter</Button> </div> </CardContent> </Card> </main> </div> );}
export default App;Klassen dynamisch kombinieren
Abschnitt betitelt „Klassen dynamisch kombinieren“Für bedingte Klassen kannst du Template Literals verwenden, wie oben im Button gezeigt. Bei komplexeren Fällen hilft die Bibliothek clsx:
npm install clsximport clsx from 'clsx';
function Button({ variant = "default", active, children }) { return ( <button className={clsx( "px-4 py-2 rounded-md text-sm font-medium cursor-pointer", variant === "primary" ? "bg-blue-600 text-white border-blue-600 hover:bg-blue-700" : "bg-white text-gray-700 border-gray-300 hover:bg-gray-100", active && "ring-2 ring-blue-400" )} > {children} </button> );}clsx ignoriert false, null und undefined — praktisch für bedingte Klassen.
Vor- und Nachteile
Abschnitt betitelt „Vor- und Nachteile“| Vorteile | Nachteile |
|---|---|
| Schnelles Prototyping — kein Kontextwechsel | Wortreiches JSX — lange className-Strings |
| Konsistente Design-Tokens (Farben, Abstände) | Du musst die Klassen-Vokabeln lernen |
| Kleine Production-Bundles dank Tree-Shaking | Schwerer lesbar bei komplexen Styles |
| Kein Naming nötig — keine Klassen erfinden | Bedingte Styles erfordern String-Zusammensetzung |