Introduction
vue-tailwind-block lets a Vue component keep its Tailwind classes in a
<tailwind> block instead of in the template. The block is YAML, grouped
under names you choose, and the template reads it from a variable called
classes.
This alert has a box, a title and a body, and two tones. Each tone changes the colors of the box and the title, so the block groups the tone classes under the part they style:
Update available
Version 2.0 is ready to install.
Payment failed
Your card was declined. Check the details and try again.
<script setup lang="ts">
defineProps<{ tone: 'info' | 'danger', title: string }>()
</script>
<template>
<div role="alert" :class="[classes.root, classes.tones[tone].root]">
<p :class="[classes.title, classes.tones[tone].title]">{{ title }}</p>
<p :class="classes.body"><slot /></p>
</div>
</template>
<tailwind lang="yaml">
root: flex flex-col gap-1 rounded-lg border px-4 py-3 text-sm
title: font-medium
body: opacity-80
# each tone colors the box and the title, the body stays neutral
tones:
info:
root: border-sky-500/30 bg-sky-500/10
title: text-sky-500
danger:
root: border-red-500/30 bg-red-500/10
title: text-red-500
</tailwind>
Adding a new tone only requires adding a key in the YAML—no template
changes or manual lookup objects needed. The classes variable is
available in both <template> and <script setup> with zero imports
required.
The block never reaches the browser: it has zero runtime overhead (0 kB).
The build compiles it into a plain JavaScript object at the top of
<script setup>, and a plugin for the Vue language tools types that
object in the editor and in vue-tsc.
When to use it
A <tailwind> block works best for multi-part components, variant
matrices, and reusable design system elements where styling logic
would otherwise clutter the template or script. For simple single-element
components with two or three static classes, leaving them inline in the
template is usually simpler.