Skip to content

Class and Style Bindings

:class and :style are enhanced versions of v-bind that understand Vue’s object and array syntax. They make dynamic styling clean and readable.

Pass an object where keys are class names and values are booleans:

<script setup lang="ts">
import { ref } from 'vue'
const isActive = ref(true)
const isDeceased = ref(false)
</script>
<template>
<div :class="{ active: isActive, deceased: isDeceased }">
Alice
</div>
</template>

The active class is applied when isActive is truthy; deceased is applied when isDeceased is truthy. Both can be true at the same time.

Pass an array of class names (strings, refs, or expressions):

<div :class="['person-card', role, isActive ? 'active' : '']">

Static class and dynamic :class can coexist — Vue merges them:

<div class="person-card" :class="{ focus: role === 'focus', clickable }">

The element always has person-card; focus and clickable are added conditionally.

PersonCard.vue uses :class to apply role-based styles:

<div class="person-card" :class="[role, { clickable }]">

This applies focus, parent, child, or spouse as a class depending on the role prop, and adds clickable when that prop is true.

The CSS then targets these classes:

.person-card.focus { border-color: var(--accent); font-weight: 700; }
.person-card.clickable { cursor: pointer; }
.person-card.clickable:hover { background: var(--surface-hover); }

Bind inline styles using camelCase property names:

<script setup lang="ts">
const accentColor = '#f472b6'
const cardWidth = 200
</script>
<template>
<div :style="{ color: accentColor, width: cardWidth + 'px' }">
Styled element
</div>
</template>

CSS property names are camelCase in the object: backgroundColor, fontSize, borderRadius.

Merge multiple style objects:

<div :style="[baseStyles, overrideStyles]">

Vue merges them — properties in later objects override earlier ones.

Prefer :class — it keeps styling in CSS where it belongs and benefits from the cascade. :style is for truly dynamic values that can’t be expressed as predefined classes: dynamically calculated pixel values, colors from a data source, etc.

  1. Create a StatusBadge.vue component that accepts a status prop: 'active' | 'inactive' | 'pending'.
  2. Use :class to apply a class matching the status value.
  3. In the CSS, give each class a different background color.
  4. In a parent, render three <StatusBadge> instances with different statuses.
  • :class="{ className: condition }" applies classes conditionally.
  • :class="['class1', condition ? 'class2' : '']" applies classes from an array.
  • Static class and dynamic :class merge automatically.
  • :style="{ camelCaseProp: value }" applies inline styles; prefer :class for most styling.