One of the lessor known, yet powerful feature of Vue.js is dynamic binding of classes. Vue.js allows you to dynamically bind multiple CSS classes to a single HTML element. It takes use of the v-bind:class directive. What’s even more interesting is that, Vue takes care of addition and removal of classes based on the truthiness of state values. Let’s have a look at how that works.
Here’s a some code I’ve written to demonstrate the idea:
<template>
<div id="app">
<div>
<input
type="checkbox"
id="showBorder"
name="showBorder"
v-model="showBorder"
/>
<label for="showBorder">Show border</label><br />
</div>
<div>
<input type="checkbox" id="boldFont" name="boldFont" v-model="boldFont" />
<label for="boldFont">Bold font</label><br />
</div>
<div>
<input
type="checkbox"
id="italicFont"
name="italicFont"
v-model="italicFont"
/>
<label for="italicFont">Italic font</label><br />
</div>
<div>
<input
type="checkbox"
id="showPadding"
name="showPadding"
v-model="showPadding"
/>
<label for="showPadding">Show padding</label><br />
</div>
<div>
<input
type="checkbox"
id="showBackground"
name="showBackground"
v-model="showBackground"
/>
<label for="showBackground">Show background</label><br />
</div>
<div class="np-preview-container">
<div class="np-preview-title">Preview</div>
<div>
<div
v-bind:class="[
'np-button',
showBorder ? 'np-button__border' : '',
italicFont ? 'np-button__italic' : '',
boldFont ? 'np-button__bold' : '',
showPadding ? 'np-button__padding' : '',
showBackground ? 'np-button__background' : '',
]"
>
Some button
</div>
</div>
</div>
<div class="np-credits">www.nightprogrammer.com</div>
</div>
</template>
<script>
export default {
name: "App",
data() {
return {
showBorder: false,
boldFont: false,
italicFont: false,
showPadding: false,
showBackground: false,
};
},
};
</script>
<style>
#app {
font-family: "Avenir", Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
padding: 8px;
}
.np-preview-title {
font-weight: 600;
}
.np-preview-container {
margin-top: 16px;
}
.np-button {
margin-top: 10px;
width: 130px;
text-align: center;
}
.np-button__padding {
padding: 4px;
}
.np-button__background {
background: #eee;
}
.np-button__border {
border: 1px solid hsl(0, 0%, 61%);
}
.np-button__italic {
font-style: italic;
}
.np-button__bold {
font-weight: bold;
}
.np-credits {
font-size: 12px;
margin-top: 24px;
}
</style>
Code language: HTML, XML (xml)
You’d notice that I’ve declared five boolean states showBorder, boldFont, italicFont, showPadding, and showBackground on line 69 through 73. These local states bind with the checkboxes I’ve shown on line 4, 13, 17, 26 and 35. Whenever any of these 5 states change, Vue re-renders the changes effectively.
Through line 49 to 53, I’ve conditionally binded the CSS classes depending on the truthiness of the states.
I’ve defined these CSS classes from line 97 to 111.
This is how the above code should render like:
You can find the demo/code from my repos below: