Dynamic Classes and Styles

In this article, I aim to provide a not so new but also not so known way of adding dynamic features into your application, ensuring that you can achieve what you wish to simply without writing boilerplate code and meddling with string concatenation.

When writing Dynamic UI Components that respond to user actions and events, we require methods to respond to these events by translating them into our DOM. Change in DOM is usually achieved by changing styles and classes based on certain reactive data that we have in our javascript.

While we can certainly do string concatenation, calculate a string and then bind a string to class or style... this method is error-prone and cumbersome at times to deal with. That's where Vue.js's clean suite of enhancements come into vue ( french for 'view' )

Quick Recap Data Binding

If you aren't familiar with what data binding is....it's essentially binding any attribute of an element in your template to the data available in your script tag, which can be props, data or computed properties.

Data binding is one of the most elegant features of Vue.js because it provides reactive data binding with a straightforward syntax using v-bind.

<div 
  v-bind:class="dynamicClass"
>Hello World!
</div>

A shorthand for data binding is but just using : and then the attribute name, which I guess anyone would prefer using more.

<div 
  :class="dynamicClass"
>Hello World!
</div>

Let's suppose that the above class is not a once initialized and stays the same kind of class it changes based on user input, so we have to use a computed property or watch to make changes to our dynamicClass variable. So things will start to look like this.

export default {
  data( ) {
    return {
      changingBoolean: false
    }
  },
  computed: {
    dynamicClass: ( ) => changingBoolean : 'text-center text-lg' ? 'text-justify text-xl'
  }
}

Looking at the code above we can see that for a simple switch in classes based on a variable we had to write so much code. So simply creating a dynamic class won't work.

Array Syntax for Classes

Enter array syntax which makes the previous task less cumbersome and also keeps it DRY at times when needed.

<article 
  :class="[changingBoolean : ? 'text-center' : 'text-justify']"
>
    Hello World!
</aside>

This looks so much cleaner than the previous method right ≧◠‿◠≦✌. But it's an array so we can add multiple values into it too :). Now we can toggle the text alignment class while flex and width will always be present.

<article 
  :class="[changingBoolean : ? 'text-center' : 'text-justify', 'flex w-2']"
>
    Hello World!
</aside>

Object Syntax for Classes

Sometimes we just want to add toggle a single class on/off when a boolean is true and nothing when it's false. Using ternary operator it will look as below

:class = [changingBoolean : ? 'text-center' : ' ', 'flex w-2']

We can do better, enter object syntax because eventually, everything is an object in javascript so why not.

:class = [ { 'text-center' : changingBoolean }, 'flex w-2']

You can also bind an object directly to class instead of keeping it inside an array and it also supports multiple togglable classes just like an array.

<article
  class="absolute"
  :class="{ active: isActive, 'text-xl': largeText }"
></article>

active is a simple string variable for class whereas isActive and largeText are boolean variables. Also if you noticed class and :class can simultaneously exist on a single element ツ

Passing in Objects

We can also pass in reactive array/object stored in our data or computed to classes. This can be a more powerful pattern at times when you have to do multiple checks and toggling which when accommodated into HTML won't look good and readable.

<nav :class="classObject"></nav>

Modifying Child Classes

Suppose we have a nice and shiny icon element we have specified several classes to it which works for most cases so we didn't bother making it a prop. But a time came when we had to change its colour in that case we want to pass down a new class to our child.

<my-icon
  :class="text-blue-600"
/>

Now the :class will be appended at the end of the class inside of our component's parent. We can obviously also provide in a simple class too.

Array and Object Syntax for Styles

The array and object syntax for classes and style looks exactly identical except for a very minor change. It's not about the truthiness of variables anymore it's about assigning them to the right CSS property.

<nav 
:style="{ marginTop: marginTop + 'px', backgroundColor: infoColor }"
>Doge Coin
</nav>

In the above example, we are assigning the color property a dynamic value and a similar operation for fontSize.

  • We can write properties as kebab case too just ensure to wrap them in quotes
  • It can be more powerful to directly pass in an object to style which is a more readable and cleaner method.

The purpose for array syntax in style reduces to allowing us to pass in multiple objects ( Duhhh that's what arrays do right :P ) for style as passing a string to style works won't make much sense in the special syntax.

<nav 
:style="[marginObject, backgroundObject]"
>Doge Coin
</nav>

Bonus Treats

Some CSS properties require us to use vendor prefixes. Vue will apply them for us implicitly but if you want to be explicit you can pass in multiple values for a single property through object syntax and providing an array of values. Vue will only render the last value in the array which the browser supports.

<ul :style="{ display: ['-webkit-box', '-ms-flexbox', 'flex'] }"></ul>

Thanks for reading! :). Please share your thoughts about the array and object syntax would you prefer them over strings?

Reach out to me on Twitter to share your feedback or for any queries. I'd be more than happy to help!

18