Zum Inhalt springen

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.

Terminal-Fenster
npm install tailwindcss @tailwindcss/vite

Füge das Vite-Plugin hinzu:

vite.config.js
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:

src/index.css
@import "tailwindcss";

Bei Tailwind gibt es keine separaten CSS-Dateien. Alle Styles stehen direkt im JSX als Utility-Klassen.

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.

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;
function CardContent({ children }) {
return (
<div className="p-5">{children}</div>
);
}
export default CardContent;
function Card({ children }) {
return (
<article className="border border-gray-200 rounded-lg overflow-hidden">
{children}
</article>
);
}
export default Card;
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;

Für bedingte Klassen kannst du Template Literals verwenden, wie oben im Button gezeigt. Bei komplexeren Fällen hilft die Bibliothek clsx:

Terminal-Fenster
npm install clsx
import 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.

VorteileNachteile
Schnelles Prototyping — kein KontextwechselWortreiches JSX — lange className-Strings
Konsistente Design-Tokens (Farben, Abstände)Du musst die Klassen-Vokabeln lernen
Kleine Production-Bundles dank Tree-ShakingSchwerer lesbar bei komplexen Styles
Kein Naming nötig — keine Klassen erfindenBedingte Styles erfordern String-Zusammensetzung