Tailwind CSS Fortgeschritten: Custom-Komponenten und Design-System

  • 05 Jan 2026
  • admin
  • 3 min
  • 320

Über Utility Classes Hinaus

Tailwind CSS ist mächtig mit Utility Classes, aber die wahre Magie entsteht, wenn Sie ein vollständiges Design-System und wiederverwendbare Komponenten erstellen.

1. Erweiterte Konfiguration

// tailwind.config.js
const defaultTheme = require('tailwindcss/defaultTheme')

module.exports = {
  content: ['./src/**/*.{html,js,jsx,tsx,vue}'],
  darkMode: 'class',
  theme: {
    extend: {
      colors: {
        primary: {
          50: '#eff6ff',
          100: '#dbeafe',
          200: '#bfdbfe',
          300: '#93c5fd',
          400: '#60a5fa',
          500: '#3b82f6',
          600: '#2563eb',
          700: '#1d4ed8',
          800: '#1e40af',
          900: '#1e3a8a',
        },
        secondary: {
          // ... Farbskala
        }
      },
      fontFamily: {
        sans: ['Inter var', ...defaultTheme.fontFamily.sans],
        display: ['Lexend', 'sans-serif'],
      },
      fontSize: {
        '2xs': ['0.625rem', { lineHeight: '1rem' }],
      },
      spacing: {
        '18': '4.5rem',
        '88': '22rem',
        '128': '32rem',
      },
      borderRadius: {
        '4xl': '2rem',
      },
      animation: {
        'fade-in': 'fadeIn 0.5s ease-out',
        'slide-up': 'slideUp 0.3s ease-out',
        'spin-slow': 'spin 3s linear infinite',
      },
      keyframes: {
        fadeIn: {
          '0%': { opacity: '0' },
          '100%': { opacity: '1' },
        },
        slideUp: {
          '0%': { transform: 'translateY(10px)', opacity: '0' },
          '100%': { transform: 'translateY(0)', opacity: '1' },
        },
      },
    },
  },
  plugins: [
    require('@tailwindcss/forms'),
    require('@tailwindcss/typography'),
    require('@tailwindcss/aspect-ratio'),
  ],
}

2. Komponenten mit @apply

/* components.css */
@layer components {
  /* Button-Basis */
  .btn {
    @apply inline-flex items-center justify-center
           px-4 py-2 rounded-lg font-medium
           transition-all duration-200
           focus:outline-none focus:ring-2 focus:ring-offset-2
           disabled:opacity-50 disabled:cursor-not-allowed;
  }

  .btn-primary {
    @apply btn bg-primary-600 text-white
           hover:bg-primary-700
           focus:ring-primary-500;
  }

  .btn-secondary {
    @apply btn bg-gray-100 text-gray-700
           hover:bg-gray-200
           focus:ring-gray-500
           dark:bg-gray-700 dark:text-gray-200;
  }

  .btn-outline {
    @apply btn border-2 border-primary-600 text-primary-600
           hover:bg-primary-50
           focus:ring-primary-500;
  }

  /* Größen */
  .btn-sm { @apply text-sm px-3 py-1.5; }
  .btn-lg { @apply text-lg px-6 py-3; }

  /* Card */
  .card {
    @apply bg-white dark:bg-gray-800
           rounded-xl shadow-lg
           overflow-hidden
           transition-shadow duration-300
           hover:shadow-xl;
  }

  .card-body {
    @apply p-6;
  }

  /* Input */
  .input {
    @apply w-full px-4 py-2
           border border-gray-300 dark:border-gray-600
           rounded-lg
           bg-white dark:bg-gray-700
           text-gray-900 dark:text-white
           placeholder-gray-400
           focus:ring-2 focus:ring-primary-500 focus:border-transparent
           transition-colors duration-200;
  }

  .input-error {
    @apply input border-red-500 focus:ring-red-500;
  }
}

3. Benutzerdefiniertes Plugin

// plugins/animations.js
const plugin = require('tailwindcss/plugin')

module.exports = plugin(function({ addUtilities, addComponents, theme }) {
  // Utilities
  addUtilities({
    '.text-gradient': {
      'background': 'linear-gradient(to right, var(--tw-gradient-stops))',
      '-webkit-background-clip': 'text',
      '-webkit-text-fill-color': 'transparent',
    },
    '.scrollbar-hide': {
      '-ms-overflow-style': 'none',
      'scrollbar-width': 'none',
      '&::-webkit-scrollbar': {
        display: 'none',
      },
    },
  })

  // Components
  addComponents({
    '.skeleton': {
      'background': 'linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%)',
      'background-size': '200% 100%',
      'animation': 'skeleton-loading 1.5s infinite',
    },
    '.glass': {
      'background': 'rgba(255, 255, 255, 0.1)',
      'backdrop-filter': 'blur(10px)',
      'border': '1px solid rgba(255, 255, 255, 0.2)',
    },
  })
}, {
  // Config-Defaults
  theme: {
    extend: {
      keyframes: {
        'skeleton-loading': {
          '0%': { 'background-position': '200% 0' },
          '100%': { 'background-position': '-200% 0' },
        },
      },
    },
  },
})

4. Erweitertes Responsive Design

<!-- Container Queries mit @container -->
<div class="@container">
  <div class="@lg:flex @lg:gap-6">
    <img class="w-full @lg:w-1/3 rounded-lg" />
    <div class="@lg:w-2/3">
      <h2 class="text-xl @lg:text-3xl">Titel</h2>
    </div>
  </div>
</div>

<!-- Breakpoint-Gruppen -->
<div class="
  flex flex-col
  sm:flex-row sm:items-center
  lg:justify-between
  xl:max-w-6xl xl:mx-auto
">
  <!-- Inhalt -->
</div>

<!-- Beliebige Werte -->
<div class="
  top-[117px]
  lg:top-[calc(theme(spacing.16)+1rem)]
  bg-[#1da1f2]
  grid-cols-[1fr_2fr_1fr]
"></div>

5. Erweiterter Dark Mode

// Dark-Mode-Umschalter
<script>
function toggleDarkMode() {
  if (document.documentElement.classList.contains('dark')) {
    document.documentElement.classList.remove('dark')
    localStorage.theme = 'light'
  } else {
    document.documentElement.classList.add('dark')
    localStorage.theme = 'dark'
  }
}

// Beim Seitenaufruf
if (localStorage.theme === 'dark' ||
    (!('theme' in localStorage) &&
     window.matchMedia('(prefers-color-scheme: dark)').matches)) {
  document.documentElement.classList.add('dark')
}
</script>

<!-- Komponente mit Dark Mode -->
<div class="
  bg-white dark:bg-gray-900
  text-gray-900 dark:text-white
  border border-gray-200 dark:border-gray-700
  shadow-lg dark:shadow-gray-900/50
">
  <h2 class="text-primary-600 dark:text-primary-400">Titel</h2>
  <p class="text-gray-600 dark:text-gray-300">Inhalt</p>
</div>

6. Produktionsoptimierung

// tailwind.config.js - Produktionsoptimierungen
module.exports = {
  // Ungenutzte Stile entfernen
  content: [
    './src/**/*.{html,js,jsx,tsx,vue}',
    './public/index.html',
  ],

  // Kritische Klassen auf Safelist setzen
  safelist: [
    'bg-red-500',
    'bg-green-500',
    'bg-blue-500',
    { pattern: /^bg-(red|green|blue)-(100|500|900)$/ },
    { pattern: /^text-(sm|base|lg|xl)$/, variants: ['hover', 'md'] },
  ],

  // Ungenutzte Core-Plugins deaktivieren
  corePlugins: {
    float: false,
    clear: false,
    skew: false,
  },
}

// PostCSS-Konfiguration
module.exports = {
  plugins: [
    require('tailwindcss'),
    require('autoprefixer'),
    ...(process.env.NODE_ENV === 'production'
      ? [require('cssnano')({ preset: 'default' })]
      : []),
  ],
}

Best Practices

  • Verwenden Sie @apply nur für häufig wiederholte Komponenten
  • Erstellen Sie ein konsistentes Token-System in der Konfiguration
  • Nutzen Sie die offiziellen Plugins (@tailwindcss/forms, typography)
  • Dokumentieren Sie Ihr Design-System
  • Testen Sie immer im Dark Mode

Fazit

Mit fortgeschrittenem Tailwind CSS können Sie professionelle, wartbare und hochperformante Design-Systeme erstellen. Der Schlüssel liegt in der richtigen Balance zwischen Utility Classes und extrahierten Komponenten.

Teilen Sie diesen Artikel

Kunden

Noch keine Kommentare. Seien Sie der Erste!

Einen Kommentar hinterlassen

Wird nicht veröffentlicht

Verwandte Artikel