Tailwind CSS hat sich 2026 zum Standard für modernes Utility-First-Styling entwickelt. Wer über die Basics hinausgehen will — Custom Tokens, eigene Plugins, Container-Queries — braucht ein tiefes Verständnis der Konfigurationsebenen. Claude Code beschleunigt genau diese fortgeschrittenen Patterns: Die KI versteht die tailwind.config.ts-Struktur, schlägt passende Plugin-APIs vor und optimiert Bundle-Größen automatisch.

1. Custom Theme und Config — tailwind.config.ts, theme.extend, Custom Colors/Fonts/Spacing, CSS Custom Properties

Der Kern jeder professionellen Tailwind-Integration ist eine durchdachte tailwind.config.ts. Mit TypeScript-Typen erhältst du IntelliSense-Unterstützung und verhindest Tippfehler bei Konfigurations-Keys.

theme.extend vs. theme überschreiben

Der entscheidende Unterschied: theme.extend ergänzt die Tailwind-Defaults, während theme sie vollständig ersetzt. Für Design-Systeme immer extend nutzen — sonst verlierst du alle Standard-Utilities.

tailwind.config.ts
import type { Config } from 'tailwindcss'

const config: Config = {
  content: ['./src/**/*.{html,ts,tsx,vue}'],
  theme: {
    extend: {
      colors: {
        brand: {
          50:  '#f5f3ff',
          500: '#7c3aed',  // Lila-Primärfarbe
          900: '#3b0764',
        },
        surface: {
          DEFAULT: 'var(--color-surface)',
          raised: 'var(--color-surface-raised)',
        },
      },
      fontFamily: {
        sans:  ['Inter Variable', 'system-ui', 'sans-serif'],
        mono:  ['JetBrains Mono', 'monospace'],
      },
      spacing: {
        '128': '32rem',
        'screen-safe': 'env(safe-area-inset-bottom)',
      },
      borderRadius: {
        '4xl': '2rem',
      },
    },
  },
  plugins: [],
}

export default config

CSS Custom Properties als Design-Token-Bridge

Der modernste Ansatz verbindet Tailwind-Klassen mit CSS Custom Properties. So kannst du Theme-Werte zur Laufzeit ändern — ideal für White-Labeling und mehrere Themes in einer Codebase.

globals.css
@layer base {
  :root {
    --color-surface:       #ffffff;
    --color-surface-raised: #f8fafc;
    --radius-card:        0.75rem;
  }

  [data-theme="dark"] {
    --color-surface:       #0f172a;
    --color-surface-raised: #1e293b;
  }
}
✦ Verfügbare Token-Klassen

bg-surface bg-surface-raised text-brand-500 font-sans font-mono p-128 rounded-4xl

TIP — Claude Code Prompt

„Erstelle eine tailwind.config.ts mit einem vollständigen Design-Token-System für eine SaaS-App: Primärfarben, Graustufen, Spacing-Scale 4px-basiert, Font-Stack mit Variable Fonts und CSS Custom Properties für Runtime-Theming."

2. Plugins — plugin(), addUtilities(), addComponents(), addBase(), matchUtilities() für Dynamic Values

Tailwind-Plugins sind der leistungsfähigste Erweiterungspunkt. Sie erlauben es dir, eigene Utility-Klassen, Komponenten und Base-Styles zu registrieren — mit Zugriff auf das komplette Theme-System.

addUtilities() — Atomic Helper Classes

plugins/scrollbar.ts
import plugin from 'tailwindcss/plugin'

export default plugin(function({ addUtilities }) {
  addUtilities({
    '.scrollbar-hide': {
      '-ms-overflow-style': 'none',
      'scrollbar-width': 'none',
      '&::-webkit-scrollbar': { display: 'none' },
    },
    '.scrollbar-thin': {
      'scrollbar-width': 'thin',
      'scrollbar-color': 'rgb(100 116 139) transparent',
    },
    '.text-balance': { 'text-wrap': 'balance' },
    '.text-pretty':  { 'text-wrap': 'pretty'  },
  })
})

addComponents() — Wiederverwendbare UI-Muster

plugins/button.ts
plugin(function({ addComponents, theme }) {
  addComponents({
    '.btn': {
      display: 'inline-flex',
      alignItems: 'center',
      justifyContent: 'center',
      borderRadius: theme('borderRadius.lg'),
      fontWeight: 600,
      transition: 'all 150ms ease',
      '&:focus-visible': {
        outline: '2px solid',
        outlineOffset: '2px',
      },
    },
    '.btn-primary': {
      backgroundColor: theme('colors.brand.500'),
      color: 'white',
      padding: `${theme('spacing.3')} ${theme('spacing.6')}`,
      '&:hover': {
        backgroundColor: theme('colors.brand.600', '#6d28d9'),
      },
    },
  })
})

matchUtilities() — Dynamische Werte mit Theme-Integration

matchUtilities() ist der Game-Changer: Damit erzeugst du Utilities, die beliebige Werte aus dem Theme oder als Arbitrary Value akzeptieren.

plugins/grid-area.ts
plugin(function({ matchUtilities, theme }) {
  matchUtilities(
    {
      'grid-area': (value) => ({ gridArea: value }),
      'col-span-custom': (value) => ({
        gridColumn: `span ${value} / span ${value}`,
      }),
    },
    { values: theme('gridTemplateAreas', {}) }
  )
})
Plugin API — Übersicht

addBase() addComponents() addUtilities() matchUtilities() addVariant() matchVariant()

3. Arbitrary Values und Varianten — [], min-[800px], data-[], group-[], peer-[], has-[], not-[]

Arbitrary Values sind Tailwinds Sicherheitsnetz für Sonderfälle — ohne Klassen-Proliferation in der Konfiguration. Der Trick liegt im sparsamen Einsatz: Wiederkehrende Werte gehören ins Theme, Einzel-Ausnahmen dürfen [] nutzen.

Wertbasierte Arbitrary Values

HTML
<!-- Exakte Pixelwerte -->
<div class="w-[743px] h-[420px] top-[13px]">

<!-- Min/Max mit Viewport -->
<div class="min-w-[320px] max-w-[1440px]">

<!-- Responsive mit Arbitrary Breakpoints -->
<div class="min-[800px]:grid-cols-3 max-[600px]:hidden">

<!-- CSS-Variablen als Wert -->
<div class="bg-[var(--brand-color)] text-[clamp(1rem,2.5vw,1.5rem)]">

Interaktive Varianten — group, peer, has

HTML — group + peer
<!-- group: Parent-State auf Children -->
<div class="group cursor-pointer">
  <h3 class="group-hover:text-violet-400 transition">Titel</h3>
  <p  class="group-hover:opacity-100 opacity-60 transition">Text</p>
</div>

<!-- peer: Sibling-State beeinflussen -->
<input type="checkbox" class="peer hidden" id="toggle">
<label for="toggle"
  class="peer-checked:bg-violet-600 peer-checked:text-white
         border rounded-lg px-4 py-2 cursor-pointer">
  Toggle
</label>

<!-- has-[]: Parent styled by child state (CSS :has) -->
<div class="has-[:focus]:ring-2 has-[:focus]:ring-violet-500">
  <input type="text" placeholder="Fokus gibt dem Parent einen Ring">
</div>

data-[] Varianten für State-Management

HTML — data-Attribute
<!-- data-[state=active] als CSS-Selektor -->
<button
  data-state="active"
  class="data-[state=active]:bg-violet-600
         data-[state=active]:shadow-lg
         data-[state=inactive]:opacity-50">
  Aktiv
</button>

<!-- not-[]:  Negations-Selektor -->
<li class="not-[:last-child]:border-b border-slate-200">Item</li>
BEST PRACTICE

Benenne group und peer mit einem Modifier wenn mehrere verschachtelt sind: group/card, group-hover/card:opacity-100. Das verhindert Konflikte bei tiefer Verschachtelung.

4. Dark Mode — class vs media, darkMode Config, @dark in CSS, System-Präferenz + manueller Toggle

Tailwinds Dark-Mode-Implementierung ist flexibler als die meisten Entwickler wissen. Die Wahl zwischen class und media hat weitreichende Konsequenzen für UX und Wartbarkeit.

class vs media — Der strategische Unterschied

Kriterium class-Strategy media-Strategy
Auslöser .dark auf <html> OS-Systemeinstellung
Manueller Toggle ✅ Ja, via JavaScript ❌ Nein
System-Präferenz Opt-in (JS nötig) Automatisch
SSR-Kompatibilität Gut (Cookie/Header) Perfekt
Empfehlung 2026 SaaS-Apps mit Einstellung Blogs, Dokumentationen
tailwind.config.ts — darkMode
const config: Config = {
  // Option A: class-basiert (empfohlen für Apps)
  darkMode: 'class',

  // Option B: CSS-Selektor (Tailwind v3.4+)
  darkMode: ['selector', '[data-theme="dark"]'],

  // Option C: media (automatisch)
  darkMode: 'media',
}

System-Präferenz + manueller Toggle kombinieren

theme-toggle.ts
type ThemeMode = 'light' | 'dark' | 'system'

function applyTheme(mode: ThemeMode): void {
  const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches
  const isDark = mode === 'dark' || (mode === 'system' && prefersDark)

  document.documentElement.classList.toggle('dark', isDark)
  localStorage.setItem('theme', mode)
}

// Beim Laden: gespeicherte Präferenz anwenden (Flash verhindern!)
;(function() {
  const saved = localStorage.getItem('theme') as ThemeMode | null
  applyTheme(saved ?? 'system')
})()

@dark in CSS — Tailwind v3.4+ Syntax

component.css
/* Neue @dark Syntax — kein doppeltes .dark: Prefix nötig */
.card {
  @apply bg-white shadow-sm border border-slate-200;

  @dark {
    @apply bg-slate-900 border-slate-700 shadow-slate-950/50;
  }
}

/* Klassisch — beide Ansätze sind valid */
.badge {
  @apply bg-slate-100 text-slate-700;
  @apply dark:bg-slate-800 dark:text-slate-200;
}
Dark Mode Utility Classes

dark:bg-slate-900 dark:text-slate-100 dark:border-slate-700 dark:ring-slate-600 dark:shadow-black/50 dark:divide-slate-700

FLASH OF UNSTYLED CONTENT (FOUC)

Das Theme-Script muss synchron im <head> vor dem ersten Paint ausgeführt werden — nicht als defer oder async. Sonst flackert das Interface beim Laden zwischen Hell und Dunkel.

5. Container Queries — @container, @md:, @lg: innerhalb von Komponenten, cqw/cqh units

Container Queries sind die bedeutendste CSS-Neuerung der letzten Jahre — und Tailwind unterstützt sie seit v3.2 nativ über das offizielle @tailwindcss/container-queries Plugin. Statt am Viewport orientiert sich das Styling am verfügbaren Platz des Parent-Containers.

Setup und grundlegende Syntax

tailwind.config.ts — Plugin aktivieren
import containerQueries from '@tailwindcss/container-queries'

const config: Config = {
  plugins: [containerQueries],
  theme: {
    extend: {
      containers: {
        'xs': '20rem',   // 320px
        'sm': '24rem',   // 384px
        // md (28rem), lg (32rem), xl (36rem) = Defaults
      },
    },
  },
}
HTML — Container Queries
<!-- @container definiert den Kontext -->
<div class="@container">
  <div class="flex flex-col @md:flex-row @lg:gap-8">
    <img class="w-full @md:w-48 @lg:w-64" src="...">
    <div class="@sm:text-lg @xl:text-2xl">
      Inhalt der sich am Container orientiert
    </div>
  </div>
</div>

<!-- Benannte Container für verschachtelte Queries -->
<aside class="@container/sidebar">
  <nav class="@sm/sidebar:block hidden">Navigation</nav>
</aside>

cqw und cqh — Container-relative Units

CSS + Tailwind — cqw/cqh Units
/* cqw = 1% der Container-Breite (wie vw, aber für Container) */
.hero-text {
  font-size: clamp(1rem, 4cqw, 3rem);
  padding: 2cqh 3cqw;
}

/* Als Arbitrary Value in Tailwind */
<h2 class="text-[clamp(1.2rem,4cqw,2.5rem)] leading-tight">
  Fluid Container Typography
</h2>
Container Query Breakpoints

@xs:hidden @sm:flex @md:grid-cols-2 @lg:text-xl @xl:gap-8 @2xl:max-w-full

WARUM CONTAINER QUERIES BESSER SIND

Eine Card-Komponente in einem 3-Spalten-Grid verhält sich anders als dieselbe Komponente in einer 1-Spalten-Sidebar. Mit Viewport-Breakpoints ist das nicht lösbar — mit Container Queries ist die Komponente selbst "responsive".

6. Performance — PurgeCSS/Content-Config, JIT-Mode, bundle size, critical CSS, Tailwind CSS v4 Migration

Tailwind generiert standardmäßig Tausende von Utility-Klassen. Ohne korrekte Konfiguration landet ein unkomprimiertes CSS-Bundle von 3–5 MB in Production. Mit richtiger Content-Konfiguration und JIT schrumpft es auf unter 20 KB.

Content-Konfiguration — Was Tailwind scannt

tailwind.config.ts — Content
const config: Config = {
  content: [
    './src/**/*.{html,js,jsx,ts,tsx,vue,svelte}',
    './components/**/*.{js,ts,jsx,tsx}',

    // Externe Bibliotheken die Tailwind-Klassen nutzen:
    './node_modules/@ui-lib/components/dist/**/*.js',

    // Dynamisch generierte Klassen NIEMALS via String-Concatenation!
    // FALSCH:  `text-${color}-500`  → wird NICHT erkannt
    // RICHTIG: Safelist oder vollständige Klassen-Namen
  ],
  safelist: [
    // Klassen die durch user-input oder CMS generiert werden:
    { pattern: /bg-(red|green|blue|violet)-(100|500|900)/ },
    'animate-pulse',
    'animate-spin',
  ],
}

Bundle-Analyse und Critical CSS

Bash — Bundle-Größe messen
# CSS Bundle-Größe nach Build:
npx tailwindcss -i ./src/input.css -o ./dist/output.css --minify
wc -c ./dist/output.css

# Gzip-Größe (realistischer Wert):
gzip -c ./dist/output.css | wc -c

# Mit Vite — automatisch optimiert:
vite build  # rollup CSS-Splitting + Purge inklusive

# Critical CSS extrahieren (für Above-the-fold):
npx critical ./dist/index.html --base ./dist/ --inline

Tailwind CSS v4 Migration — Was sich ändert

CSS — Tailwind v4 Konfiguration (CSS-first)
/* v4: Keine tailwind.config.ts mehr — Konfiguration direkt in CSS */ @import "tailwindcss"; @theme { --color-brand-500: #7c3aed; --color-brand-600: #6d28d9; --font-sans: 'Inter Variable', system-ui; --spacing-128: 32rem; --radius-4xl: 2rem; } /* v4 nutzt Lightning CSS statt PostCSS — deutlich schneller */ /* Automatisches Content-Scanning — keine content[] config nötig */ /* Alle Farben automatisch als oklch() definiert */
Feature Tailwind v3 Tailwind v4
Konfiguration tailwind.config.ts CSS @theme Block
Build-Tool PostCSS Lightning CSS (10× schneller)
Content-Scan Manuell konfiguriert Automatisch
Farb-Format hex / rgb oklch() (P3-Farbraum)
Breaking Changes Prefix-Änderungen, neue Utility-Namen
Migration Tool npx @tailwindcss/upgrade
MIGRATIONS-STRATEGIE 2026

Neue Projekte direkt mit v4 starten. Bestehende v3-Projekte: npx @tailwindcss/upgrade ausführen und automatisch erkannte Breaking Changes reviewen. Plugins die matchUtilities() nutzen sind meist kompatibel — reine CSS-Plugins ggf. anpassen.

Performance Checkliste — Production
  • content-Array vollständig konfiguriert (alle Template-Pfade)
  • ✅ Keine dynamisch konkatenierte Klassen-Namen
  • safelist nur für CMS/User-generierte Klassen
  • ✅ CSS minifiziert (--minify Flag oder Vite)
  • ✅ Gzip/Brotli auf Server aktiviert
  • ✅ Critical CSS für Above-the-fold extrahiert
  • ✅ Bundle-Größe vor Deploy gemessen (< 20 KB gzipped ist erreichbar)

Mit Claude Code Tailwind auf Enterprise-Level

Von Custom Plugins bis Container Queries — Claude Code generiert production-ready Tailwind-Konfigurationen, schreibt typsichere Plugins und optimiert Bundle-Größen automatisch.

Kostenlos ausprobieren →