Tips & Tricks (Aktualisiert: 2.6.2026)

Tailwind CSS mit Claude Code: Praxis-Tipps für stabile UI

Tailwind CSS mit Claude Code: Design Tokens, responsive UI, Dark Mode, Komponenten, Safelist und visuelle Checks.

Tailwind CSS mit Claude Code: Praxis-Tipps für stabile UI

Tailwind CSS ist stark, weil du Oberflächen mit kleinen Utility-Klassen wie p-4, grid, text-sm und rounded-lg baust. Claude Code beschleunigt diesen Prozess, weil es dein Repository lesen, Dateien bearbeiten, Befehle ausführen und Änderungen prüfen kann. Ohne klare Vorgaben entstehen aber schnell lange className-Ketten, uneinheitliche Farben, mobile Layoutfehler, unvollständiger Dark Mode oder dynamische Klassen, die im Produktions-CSS fehlen.

Dieser Leitfaden zeigt einen praktischen Workflow für Tailwind CSS mit Claude Code. Es geht um Design Tokens, responsive Utilities, Komponenten-Extraktion, das Vermeiden von Class Soup, Dark Mode, Formulare, Buttons, Cards, Safelist, Content Scanning und visuelle Checks mit Playwright. Die Beispiele nutzen React + TypeScript, die Denkweise passt aber ebenso zu Astro, Next.js, Remix oder Vite.

Als offizielle Quellen dienen Tailwind Theme variables, Responsive design, Dark mode, Detecting classes in source files und Adding custom styles. Für React mit TypeScript siehe den React TypeScript Guide. Claude Code selbst ist in der offiziellen Dokumentation beschrieben. Für Screenshot-Vergleiche ist Playwright Visual comparisons relevant.

Wenn deine Prompts noch zu allgemein sind, lies zuerst 5 Tipps für bessere Prompts. Wenn du eine vollständige mobile App-Erfahrung verbessern willst, passt dazu der PWA-Leitfaden.

Erst auditieren, dann umbauen

Bitte Claude Code nicht sofort um eine Umgestaltung. Tailwind-Probleme entstehen oft durch verteilte kleine Entscheidungen: Farben, Abstände, Breakpoints, Formularzustände, Dark Mode, CTAs, Anzeigenflächen und Codeblöcke. Lass zuerst einen Bericht erstellen.

Prüfe die Tailwind-CSS-Nutzung in diesem Repository. Bearbeite noch keine Dateien.
Erstelle einen Bericht zu:

- vorhandenen Design Tokens für color, spacing, radius, shadow und typography
- React-Komponenten mit sehr langen className-Werten
- Layouts, die bei 375px, 768px oder 1440px brechen können
- Light/Dark-Mode-Abdeckung
- wiederholten Styles in forms, buttons, cards und badges
- dynamischen Tailwind-Klassen mit Produktionsrisiko
- vorhandenen visuellen Checks mit Playwright, Storybook oder Browser

Masa hat bei ClaudeCodeLab einmal Card-Abstände nur am Desktop geprüft. Mobil wurden CTA am Artikelende und Anzeigenbereich zu eng. Eine Tailwind-Klasse wirkt lokal, kann aber Lesbarkeit und Conversion beeinflussen.

Design Tokens zentralisieren

Design Tokens sind benannte Werte für Farben, Abstände, Fonts, Radius, Schatten und Breakpoints. Tailwind CSS v4 nutzt @theme; daraus entstehen Utilities wie bg-brand-600 oder rounded-card. In älteren Projekten mit tailwind.config.ts legst du dieselben Werte in theme.extend ab.

/* src/styles/app.css */
@import "tailwindcss";

@custom-variant dark (&:where(.dark, .dark *));

@theme {
  --font-sans: Inter, system-ui, sans-serif;
  --color-brand-50: #eef6ff;
  --color-brand-100: #d9ebff;
  --color-brand-600: #2563eb;
  --color-brand-700: #1d4ed8;
  --color-ink: #111827;
  --color-muted: #6b7280;
  --color-surface: #ffffff;
  --color-danger: #dc2626;
  --radius-card: 0.75rem;
  --shadow-card: 0 16px 40px rgb(15 23 42 / 0.08);
}

Ein guter Auftrag an Claude Code lautet: „Nutze vorhandene Tokens wie brand, surface und danger; füge neue @theme-Werte nur hinzu, wenn sie wiederverwendbar sind.“ Das ist zuverlässiger als „mach das Blau schöner“, was schnell zu einer Mischung aus blue, sky und indigo führt.

Responsive immer mobile-first denken

Tailwind ist mobile-first. Die Basisklasse gilt für kleine Bildschirme, sm:, md: und lg: ergänzen größere Ansichten. Wer mit Desktop beginnt, flickt mobile Zustände oft zu spät.

Verbessere das Product Grid mit Tailwind CSS.
Anforderungen:
- 1 Spalte bei 375px, 2 Spalten ab 640px, 3 Spalten ab 1024px
- Bilder bleiben quadratisch
- Cards haben konsistente Höhe
- CTA-Button sitzt unten in der Card
- Product props type nicht ändern
- Danach Mobile- und Desktop-Screenshots prüfen
type Product = {
  id: string;
  name: string;
  price: number;
  imageUrl: string;
};

export function ProductGrid({ products }: { products: Product[] }) {
  return (
    <section className="grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3">
      {products.map((product) => (
        <article
          key={product.id}
          className="flex h-full flex-col overflow-hidden rounded-card border border-slate-200 bg-surface shadow-card dark:border-slate-800 dark:bg-slate-950"
        >
          <img
            src={product.imageUrl}
            alt={product.name}
            className="aspect-square w-full object-cover"
          />
          <div className="flex flex-1 flex-col p-4">
            <h3 className="line-clamp-2 text-base font-semibold text-ink dark:text-white">
              {product.name}
            </h3>
            <p className="mt-2 text-sm text-muted dark:text-slate-400">
              {product.price.toLocaleString("de-DE", {
                style: "currency",
                currency: "EUR",
              })}
            </p>
            <button className="mt-auto rounded-lg bg-brand-600 px-4 py-2.5 text-sm font-semibold text-white hover:bg-brand-700 focus:outline-none focus:ring-2 focus:ring-brand-600 focus:ring-offset-2 dark:focus:ring-offset-slate-950">
              Details ansehen
            </button>
          </div>
        </article>
      ))}
    </section>
  );
}

aspect-square hält das Bild stabil, flex h-full flex-col stabilisiert die Card, und mt-auto hält den CTA unten.

Class Soup durch kleine Komponenten vermeiden

Class Soup entsteht, wenn ein className so lang wird, dass Basis, Variante und Sonderfall nicht mehr erkennbar sind. Du musst nicht alles mit @apply verstecken. Extrahiere vor allem wiederholte Buttons, Cards, Badges und Inputs.

import type { ButtonHTMLAttributes, ReactNode } from "react";

type ButtonVariant = "primary" | "secondary" | "danger";

const buttonVariants: Record<ButtonVariant, string> = {
  primary: "bg-brand-600 text-white hover:bg-brand-700 focus:ring-brand-600",
  secondary:
    "border border-slate-300 bg-white text-slate-900 hover:bg-slate-50 focus:ring-slate-400 dark:border-slate-700 dark:bg-slate-900 dark:text-white",
  danger: "bg-danger text-white hover:bg-red-700 focus:ring-danger",
};

function cn(...classes: Array<string | false | null | undefined>) {
  return classes.filter(Boolean).join(" ");
}

type ButtonProps = ButtonHTMLAttributes<HTMLButtonElement> & {
  variant?: ButtonVariant;
  loading?: boolean;
  children: ReactNode;
};

export function Button({
  variant = "primary",
  loading = false,
  disabled,
  className,
  children,
  ...props
}: ButtonProps) {
  return (
    <button
      className={cn(
        "inline-flex min-h-10 items-center justify-center rounded-lg px-4 py-2 text-sm font-semibold transition focus:outline-none focus:ring-2 focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-60 dark:focus:ring-offset-slate-950",
        buttonVariants[variant],
        className,
      )}
      disabled={disabled || loading}
      {...props}
    >
      {loading ? "Wird verarbeitet..." : children}
    </button>
  );
}

Wichtig: Klassen sollten als vollständige Strings vorkommen. bg-${color}-600 kann vom Tailwind-Scanner übersehen werden.

Dark Mode, Formulare und CTA zusammen prüfen

Dark Mode ist nicht nur ein dunkler Hintergrund. Text, Border, Shadow, Input, Error, Disabled State und Focus Ring müssen ebenfalls geprüft werden. Formulare und CTAs sind Teil des Umsatzpfads, daher reicht der Erfolgszustand nicht.

"use client";

import type { FormEvent } from "react";

type LeadFormProps = {
  onSubmit: (values: { email: string; message: string }) => void;
  error?: string;
};

export function LeadForm({ onSubmit, error }: LeadFormProps) {
  function handleSubmit(event: FormEvent<HTMLFormElement>) {
    event.preventDefault();
    const formData = new FormData(event.currentTarget);
    onSubmit({
      email: String(formData.get("email") ?? ""),
      message: String(formData.get("message") ?? ""),
    });
  }

  return (
    <form
      onSubmit={handleSubmit}
      className="space-y-4 rounded-card border border-slate-200 bg-white p-5 shadow-card dark:border-slate-800 dark:bg-slate-950"
    >
      <label className="block text-sm font-medium text-slate-900 dark:text-white">
        E-Mail
        <input
          name="email"
          type="email"
          required
          aria-describedby={error ? "lead-form-error" : undefined}
          className="mt-1 w-full rounded-lg border border-slate-300 bg-white px-3 py-2 text-sm text-slate-900 outline-none focus:border-brand-600 focus:ring-2 focus:ring-brand-600/20 dark:border-slate-700 dark:bg-slate-900 dark:text-white"
          placeholder="you@example.com"
        />
      </label>

      {error ? (
        <p id="lead-form-error" className="text-sm font-medium text-danger">
          {error}
        </p>
      ) : null}

      <button className="w-full rounded-lg bg-brand-600 px-4 py-2.5 text-sm font-semibold text-white hover:bg-brand-700 focus:outline-none focus:ring-2 focus:ring-brand-600 focus:ring-offset-2 dark:focus:ring-offset-slate-950">
        Beratung anfragen
      </button>
    </form>
  );
}

Für Barrierefreiheit passt der Claude Code Accessibility Guide als ergänzende interne Referenz.

Safelist und Content Scanning beachten

Tailwind erzeugt CSS aus den Klassen, die es in Quelltexten findet. Dynamisch zusammengesetzte Klassen fehlen leicht im Produktions-CSS. Nutze statische Maps.

type Status = "success" | "warning" | "danger";

const statusClasses: Record<Status, string> = {
  success: "bg-emerald-50 text-emerald-700 ring-emerald-600/20",
  warning: "bg-amber-50 text-amber-800 ring-amber-600/20",
  danger: "bg-red-50 text-red-700 ring-red-600/20",
};

export function StatusBadge({ status, label }: { status: Status; label: string }) {
  return (
    <span
      className={`inline-flex items-center rounded-full px-2.5 py-1 text-xs font-semibold ring-1 ring-inset ${statusClasses[status]}`}
    >
      {label}
    </span>
  );
}

Wenn Klassen aus einem externen UI-Paket oder CMS kommen, verwende @source oder @source inline() sparsam.

@import "tailwindcss";

@source "../node_modules/@acme/ui-kit";
@source inline("bg-emerald-50");
@source inline("text-emerald-700");
@source inline("bg-amber-50");
@source inline("text-amber-800");

Visuell mit Screenshots prüfen

Ein erfolgreicher Build beweist nicht, dass die UI korrekt aussieht. Mit Playwright kannst du wichtige Breiten festhalten.

import { expect, test } from "@playwright/test";

const viewports = [
  { name: "mobile", size: { width: 375, height: 812 } },
  { name: "tablet", size: { width: 768, height: 1024 } },
  { name: "desktop", size: { width: 1440, height: 960 } },
];

for (const viewport of viewports) {
  test(`pricing page visual check - ${viewport.name}`, async ({ page }) => {
    await page.setViewportSize(viewport.size);
    await page.goto("/pricing");
    await expect(page.getByRole("main")).toHaveScreenshot(
      `pricing-${viewport.name}.png`,
      { maxDiffPixelRatio: 0.01 },
    );
  });
}

Bitte Claude Code danach um geänderte Dateien, Risiken, geprüfte Viewports, Dark-Mode-Status und manuelle Schritte, falls Playwright nicht vorhanden ist.

Use Cases und typische Fehler

Use CaseAuftrag an Claude CodeTailwind-Fokus
Landing PageHero, CTA, Preise und Testimonials gemeinsam prüfenAbstand, Hierarchie, CTA
SaaS DashboardTabellen, Filter, Sidebar, Empty States ordnenDichte, Overflow, Sticky Header
Lead FormInput, Error, Success, Loading, Disabled abdeckenFocus Ring, Labels, mobile Targets
Content SiteText, Codeblöcke, Anzeigen und CTA zusammen prüfenLesebreite, Code-Scroll, interne Links

Häufige Fehler sind dynamische Klassen, reine Desktop-Reviews, halber Dark Mode, übermäßiges @apply, zu viele ähnliche Farben, vergessene Formularfehler und fehlende Screenshots.

CTA und getestetes Ergebnis

Tailwind-Verbesserungen sollten den Geschäftspfad stützen: CTA am Artikelende, Pricing Card, Beratungsformular oder Download. ClaudeCodeLab bietet ein kostenloses Claude Code Cheatsheet, Produkte und Templates sowie Training oder Beratung für Teams.

Beim Test auf ClaudeCodeLab-Seiten brachten der Audit-Prompt und der 375px-Screenshot den größten Nutzen. Sie fanden CTA-Abstände, Formular-Focus und Dark-Mode-Kontrastprobleme, bevor daraus eine weitere Aufräumrunde für lange className-Strings wurde.

#Claude Code #Tailwind CSS #CSS #Design #Frontend
Kostenlos

Kostenloses PDF: Claude-Code-Cheatsheet

E-Mail eintragen und eine Seite mit Befehlen, Review-Gewohnheiten und sicheren Workflows herunterladen.

Wir schützen Ihre Daten und senden keinen Spam.

Masa

Über den Autor

Masa

Engineer für praktische Claude-Code-Workflows und Team-Einführung.