Tailwind CSS mit Vue
Utility-first CSS trifft reaktive Templates – die produktivste Kombination für moderne UIs.
Warum Tailwind + Vue?
Tailwind CSS und Vue ergänzen sich perfekt: Tailwind liefert die Utility-Klassen, Vue macht sie mit :class-Bindings dynamisch. Das Ergebnis ist schnelleres Prototyping, konsistentes Design und keine CSS-Dateien mehr, die niemand aufräumt.
Setup mit Vite
In Nuxt 3 ist das Setup dank des offiziellen Vite-Plugins minimal:
npm install tailwindcss @tailwindcss/viteimport tailwindcss from '@tailwindcss/vite'
export default defineNuxtConfig({
vite: {
plugins: [
tailwindcss(),
],
},
})@import 'tailwindcss';Tailwind v4
Seit Tailwind v4 brauchst du keine tailwind.config.js mehr. Die Konfiguration passiert direkt in CSS mit @theme. Das Vite-Plugin ersetzt den alten PostCSS-Ansatz.
Tailwind in Templates
Utility-Klassen direkt im Template – keine Kontextwechsel mehr zwischen HTML und CSS:
<template>
<div class="max-w-sm rounded-xl border border-gray-200 bg-white p-6 shadow-sm">
<img
:src="avatar"
:alt="name"
class="w-16 h-16 rounded-full object-cover ring-2 ring-emerald-400"
/>
<h3 class="mt-4 text-lg font-semibold text-gray-900">{{ name }}</h3>
<p class="text-sm text-gray-500 mt-1">{{ rolle }}</p>
<div class="mt-4 flex gap-2">
<span
v-for="skill in skills"
:key="skill"
class="px-2 py-1 text-xs font-medium rounded-full bg-emerald-50 text-emerald-700"
>
{{ skill }}
</span>
</div>
</div>
</template>Dynamische Klassen mit :class
Vue bietet drei Syntaxen für dynamische Klassen – alle funktionieren perfekt mit Tailwind:
<script setup>
import { ref } from 'vue'
const istAktiv = ref(false)
const status = ref('success') // 'success' | 'warning' | 'error'
</script>
<template>
<!-- 1. Objekt-Syntax: Klasse wird bei true hinzugefügt -->
<button
:class="{
'bg-emerald-500 text-white': istAktiv,
'bg-gray-100 text-gray-700': !istAktiv,
}"
class="px-4 py-2 rounded-lg font-medium transition-colors"
@click="istAktiv = !istAktiv"
>
{{ istAktiv ? 'Aktiv' : 'Inaktiv' }}
</button>
<!-- 2. Array-Syntax: Klassen zusammensetzen -->
<div :class="[
'p-4 rounded-lg border',
istAktiv ? 'border-emerald-400' : 'border-gray-200',
]">
Array-Syntax Beispiel
</div>
<!-- 3. Computed für komplexe Logik -->
<span :class="statusKlassen">{{ status }}</span>
</template>
<script setup>
const statusKlassen = computed(() => {
const basis = 'px-3 py-1 rounded-full text-sm font-medium'
const farben = {
success: 'bg-green-100 text-green-800',
warning: 'bg-amber-100 text-amber-800',
error: 'bg-red-100 text-red-800',
}
return [basis, farben[status.value]]
})
</script>Statische + dynamische Klassen
Du kannst class und :class am selben Element verwenden. Vue merged beide automatisch. Nutze class für feste Utilities und :class für den dynamischen Teil.
Komponenten extrahieren vs. @apply
Wenn sich Utility-Kombinationen wiederholen, hast du zwei Optionen:
<!-- ✅ BESSER: Vue-Komponente extrahieren -->
<!-- components/UiButton.vue -->
<template>
<button
class="px-4 py-2 rounded-lg font-medium transition-colors
bg-emerald-500 text-white hover:bg-emerald-600
disabled:opacity-50 disabled:cursor-not-allowed"
>
<slot />
</button>
</template>
<!-- ⚠️ OKAY für nicht-komponentenfähige Elemente: @apply -->
<style>
.prose-content h2 {
@apply text-2xl font-bold mt-8 mb-4 text-gray-900;
}
</style>Faustregel
Wenn du Tailwind-Klassen wiederverwenden willst, extrahiere eine Vue-Komponente – nicht eine CSS-Klasse mit @apply. Das ist der Vue-Weg und bietet dir Props, Slots und Logik obendrein.
Dark Mode
Tailwind unterstützt Dark Mode über den dark:-Modifier. Standardmäßig reagiert er auf die .dark-Klasse am <html>-Element:
<template>
<div class="bg-white dark:bg-gray-900 text-gray-900 dark:text-gray-100
border border-gray-200 dark:border-gray-700
rounded-xl p-6 transition-colors">
<h3 class="text-lg font-bold">Dark Mode Karte</h3>
<p class="text-gray-500 dark:text-gray-400 mt-2">
Dieser Text passt sich automatisch an.
</p>
<button
class="mt-4 px-4 py-2 rounded-lg
bg-emerald-500 hover:bg-emerald-600
dark:bg-emerald-600 dark:hover:bg-emerald-500
text-white font-medium transition-colors"
>
Aktion
</button>
</div>
</template>Rails-Vergleich
In Rails musst du Dark Mode manuell mit CSS-Variablen oder Media Queries bauen. Mit Tailwind schreibst du einfach dark:bg-gray-900 und es funktioniert. Kombiniert mit Vue's reaktivem Theme-Toggle hast du Dark Mode in Minuten statt Stunden.
Live-Demo: Dynamische Tailwind-Klassen
Beispiel-Karte
Diese Karte wird komplett durch dynamische Tailwind-Klassen gesteuert. Ändere die Optionen oben!