18
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' )
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.
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>
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 whereasisActive
andlargeText
are boolean variables. Also if you noticed class and:class
can simultaneously exist on a single element ツ
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>
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.
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>
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