Class & Style Bindings
Class and style bindings let you switch presentation reactively. Vue accepts strings, arrays, or objects — pick the shape that matches your data.
v-bind:class and v-bind:style
EXAMPLE
<script setup>
import { ref, computed } from 'vue';
const active = ref(true);
const level = ref('warn');
const size = ref(24);
const error = ref('');
const alertClass = computed(() => ({
'alert': true,
'alert--active': active.value,
[`alert--${level.value}`]: true,
'alert--error': !!error.value,
}));
</script>
<template>
<!-- 1) Object syntax — keys are class names, values are booleans -->
<div :class="{ active: active, disabled: !active }"></div>
<!-- 2) Array syntax — mix static + dynamic classes -->
<div :class="['card', active ? 'active' : 'idle', { highlighted: error }]"></div>
<!-- 3) Computed — clearer for many conditions -->
<div :class="alertClass">{{ error || 'All good' }}</div>
<!-- 4) On a component — Vue merges with the component's root class -->
<UserCard :class="['shadow', { selected: active }]" />
<!-- 5) Inline style — object syntax, kebab OR camel -->
<div :style="{ color: 'crimson', fontSize: size + 'px' }"></div>
<div :style="{ 'background-color': error ? '#fee' : '#eef' }"></div>
<!-- 6) Array of style objects — last wins on conflicts -->
<div :style="[baseStyle, error && errorStyle]"></div>
<!-- 7) CSS custom properties via :style — themeable components -->
<div :style="{ '--accent': active ? '#0ea5e9' : '#94a3b8' }" class="themed">…</div>
</template>
<style scoped>
.themed { color: var(--accent); border-color: var(--accent); }
</style>
Why it matters
CSS custom properties via :style are the cleanest way to theme a component without an inline-style mess — pass tokens through, your CSS reads them through var().
Tip: Tweak the snippet with Try it Yourself », then sit the quiz at the bottom of the page.
Example
Example
<div :class="{ active: isActive, error: hasError }"></div>
<div :style="{ color: textColor }"></div>
Try it Yourself »
Discussion
Loading…