Style Vue components — scoped styles built into SFCs, Tailwind utility classes with :class bindings, and shadcn-vue components you own and can restyle freely.
Why: a <style scoped> block applies its rules ONLY inside the current component — no naming conventions, no leaking into the rest of the app. It ships with every SFC; nothing to install.
<script setup lang="ts"></script>
<template>
<section class="card">
<h3>Only this component's .card is affected</h3>
</section>
</template>
<style scoped>
/* scoped = these rules apply ONLY inside this component */
.card {
border: 1px solid #ddd;
border-radius: 12px;
padding: 16px;
}
</style>Why: utility classes live right on the element, and :class merges computed classes with the static ones — conditional styles become ordinary JavaScript. Note: the Tailwind course covers the utilities themselves; this is the Vue side of the workflow.
<script setup lang="ts">
defineProps<{ kind: 'info' | 'error' }>()
</script>
<template>
<!-- class holds what every alert shares; :class adds one set or the other -->
<div
class="rounded-lg border p-4 text-sm"
:class="
kind === 'error'
? 'border-red-300 bg-red-50 text-red-800'
: 'border-blue-300 bg-blue-50 text-blue-800'
"
>
{{ kind === 'error' ? 'Something went wrong.' : 'Heads up!' }}
</div>
</template>Why: instead of installing a component library you cannot change, shadcn-vue copies accessible components — built on Reka UI primitives, styled with Tailwind — into your project. You own the code; restyle or rewrite anything.
$ pnpm dlx shadcn-vue@latest init$ pnpm dlx shadcn-vue@latest add button dialog<script setup lang="ts">
// The components are copied into YOUR project — open and edit them freely
import { Button } from '@/components/ui/button'
import {
Dialog,
DialogContent,
DialogHeader,
DialogTitle,
DialogTrigger,
} from '@/components/ui/dialog'
</script>
<template>
<Dialog>
<!-- as-child lets the Button itself act as the thing that opens the dialog -->
<DialogTrigger as-child>
<Button variant="destructive">Delete account</Button>
</DialogTrigger>
<DialogContent>
<DialogHeader>
<DialogTitle>Are you absolutely sure?</DialogTitle>
</DialogHeader>
<Button variant="outline">Cancel</Button>
</DialogContent>
</Dialog>
</template>