Ü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.