Dynamic Styles With Vue.js


While this tutorial has content that we believe is of great benefit to our community, we have not yet tested or edited it to ensure you have an error-free learning experience. It's on our list, and we're working on it! You can help us out by using the "report an issue" button at the bottom of the tutorial.

Vue.js allows for binding styles and classes dynamically to elements with the v-bind:style and v-bind:class directives.

Dynamically Binding Styles

Let’s say we want to increase or decrease the font size based on user input. To this end, Vue provides us with the v-bind:style directive.

Here’s our data model:

data() {
  return {
    fontSize: 10

Let’s use two buttons in the template and an inline expression that will increment and decrement the fontSize variable on the click event:

Binding multiple styles to an element

<button v-on:click="fontSize++">
  Increase font size
<button v-on:click="fontSize--">
  Decrease font size

<p v-bind:style="{ fontSize: fontSize + 'px' }">
  Font size is: {{ fontSize }}

After the buttons we have a paragraph that has a v-bind:style attached to it. This attaches the fontSize model value to the css font-size property.

Note: camelCase will be evaluated to dash-case syntax (ie: fontSize to font-size).

Rather than having all the styles in the inline expression, we can keep a styles object in the model and apply it to the v-bind:style directive as well.

Array of Styles

If needed, we can add multiple style objects to the v-bind:style directive. In the data model, you can have the style objects as follows:

baseStyles: {
  color: 'red'
overrideStyles: {

In the template, simply provide an array of the style objects that should be applied:

<p v-bind:style="[baseStyles, overrideStyles]">
  baseStyles and overrideStyles

Note the importance of the order of the items in the array, with later items overriding previous ones.

Automatic Prefixing

Vue automatically adds the required vendor prefixes to help keep the syntax clean For styles that need prefixes such as -moz or -webkit.

Binding Classes Dynamically

Applying styles directly can get complex as the requirements change. To help with this, the v-bind:class directive provides us with a way to bind classes to an element.

For example, when a menu item is selected, we may need to underline the element, change it’s color and change the font weight.

While this is possible to implement with a style binding, it’s much cleaner to apply a class when the item is selected.

To achieve this, we use a set of menu items and the selected item in the data model. The selected value will be set by default.

data() {
  return {
    selected: 'Home',
    menuItems: ['Home', 'About', 'Contact']

When an item is clicked, we can set the value of the selected variable to be equal the current item. With this in place, we use the v-bind:class directive in order to set the selected class on the item if the selected variable is equal to the current item:

  <li v-for="item in menuItems"
    v-on:click="selected = item"
    v-bind:class="{ selected: selected == item}">

Binding Multiple Classes

We can apply multiple classes to an item by passing in an array of classes to the v-bind:class directive.

The class array can be defined in the data model like this:

data() {
  return {
    classArray: ['selected', 'underlined']

And in the template, we can refer to the same array using the v-bind:class directive.

<p v-bind:class="[classArray]">
  Multiple classes {{ classArray }}

This will apply both the selected and the underlined classes to the element. We can change the array in the model dynamically, and the changes will be reflected in the template as well.


Creative Commons License