How to use dynamic classes in Vue

Using dynamic classes in Vue enables conditional styling, interactive UI states, and responsive design patterns based on component data and user interactions. As the creator of CoreUI, a widely used open-source UI library, I’ve implemented dynamic class binding in numerous Vue components for theme switching, active states, and conditional styling in enterprise applications. From my expertise, the most flexible approach is to use Vue’s class binding syntax with objects and arrays. This method provides clean template syntax, reactive class updates, and powerful conditional styling capabilities for complex UI scenarios.

Use class binding with objects and arrays for dynamic CSS classes based on component state.

<template>
  <div>
    <!-- Object syntax for conditional classes -->
    <button
      :class="{
        'btn': true,
        'btn-primary': isPrimary,
        'btn-large': isLarge,
        'btn-disabled': isDisabled,
        'btn-active': isActive
      }"
      @click="handleClick"
    >
      {{ label }}
    </button>

    <!-- Array syntax for multiple dynamic classes -->
    <div :class="[baseClasses, sizeClass, { 'highlighted': isHighlighted }]">
      Dynamic content
    </div>

    <!-- Computed property for complex logic -->
    <nav :class="navigationClasses">
      Navigation
    </nav>
  </div>
</template>

<script setup>
import { ref, computed } from 'vue'
import { useStore } from 'vuex' // or your preferred store solution

const props = defineProps(['label', 'variant', 'size', 'disabled'])

const store = useStore()

const isActive = ref(false)
const isHighlighted = ref(false)

const isPrimary = computed(() => {
  return props.variant === 'primary'
})

const isLarge = computed(() => {
  return props.size === 'large'
})

const isDisabled = computed(() => {
  return props.disabled
})

const baseClasses = computed(() => {
  return 'component-base'
})

const sizeClass = computed(() => {
  return `component-${props.size || 'medium'}`
})

const navigationClasses = computed(() => {
  return {
    'nav': true,
    'nav-dark': store.state.darkMode,
    'nav-collapsed': store.state.sidebarCollapsed
  }
})

const handleClick = () => {
  isActive.value = !isActive.value
}
</script>

Vue’s class binding uses object syntax { 'class-name': condition } for conditional classes and array syntax ['class1', 'class2', { 'conditional': condition }] for mixed static and dynamic classes. Conditions are evaluated reactively, automatically updating classes when data changes. Use computed properties for complex class logic that depends on multiple data properties or store state. This approach provides excellent performance through Vue’s reactivity system and clean separation of styling logic from templates.

Best Practice Note:

This is the same approach we use in CoreUI Vue components for theme switching and responsive design patterns. Use computed properties for complex class logic, combine with CSS transitions for smooth state changes, and consider using CSS custom properties (variables) for dynamic styling values that change frequently.


Speed up your responsive apps and websites with fully-featured, ready-to-use open-source admin panel templates—free to use and built for efficiency.


About the Author

Subscribe to our newsletter
Get early information about new products, product updates and blog posts.
How to return multiple values from a JavaScript function
How to return multiple values from a JavaScript function

CSS Selector for Parent Element
CSS Selector for Parent Element

How to Remove the Last Character from a String in JavaScript
How to Remove the Last Character from a String in JavaScript

How to Center a Button in CSS
How to Center a Button in CSS

Answers by CoreUI Core Team