Style Binding with Vue.js

Vue.js allows for binding styles and classes dynamically to elements with the v-bind:style and v-bind:class directives. Previously we learned about how to handle events in Vue.js.

Vue Style Binding

Let’s say we want to dynamically set the font size or margin of any element based on the user input. Vue provides us dynamic style binding with v-bind:style. Consider the following data model for this example.

data() {
  return {
    margin: 20
  }
}

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

<button v-on:click="margin++">
  Increase margin
</button>
<button v-on:click="margin--">
  Decrease margin
</button>

<p v-bind:style="{ margin: margin + 'px' }">
  Margin is: {{ margin }}
</p>

After the buttons, we have a paragraph that has a v-bind:style attached to it. This attaches the margin variable value to the CSS margin property.

Note: here 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 style object in the model and apply it to the v-bind:style directive as well.

Array of styles | Binding Multiple styles

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

basicStyles: {
  fontWeight:'800',
  color: 'red'
},
extraStyles: {
  color:'blue'
},

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

<div v-bind:style="[basicStyles, extraStyles]">
  Applied styles
</div>

Here we see that the importance of the order of the items in the array, the later items will override previous ones.

Automatic Prefixing

Talking about the cross-browser compatibility. 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 direct styles is not the best practice and it can get complex as the requirements change. To our rescue with this, the v-bind:class directive provides us with a way so that we can bind classes to any element.

For example, when a todo item is selected, we may need to change its color and change the font-weight.

Let’s consider this data model for example.

data() {
  return {
    selected: 'item 1',
    items: ['item 1', 'item 2', 'item 3']
  }
}

When an item is clicked, we set the value of the selected variable to be equal to 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:

<div>
  <p v-for="item in items"
    v-on:click="selected = item"
    v-bind:class="{ selected: selected == item}">
      {{item}}
  </p>
</div>

Binding Multiple Classes

Similar to how we applied multiple styles using array syntax we can also 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 {
    classes: ['selected', 'bolder']
  }
}

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

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

This will apply both the selected and the bolder classes to the element. When we change the array in the model dynamically, the changes will be reflected in the template automatically.

Imad

I am a Software Engineer with ample experience in making games, websites, mobile apps and augmented reality solutions.

Pin It on Pinterest