Blog

Add dynamic style tag inside Vue template tag

So here is a common situation I was into recently. I am building a portal using NuxtJS, NodeJS & MongoDB stack and the requirement was to store design preferences for specific user. So a user can login and set up their profile text color, background color, button styles etc. And the first question popped in my mind was, how do I add all these styles dynamically in NuxtJS (or you can say VueJS)? There are couple of solution, some of which can work and some doesn’t.

1. By binding style attribute

This is a very common method as you can dynamically bind any attributes to html tags in Vue JS. So doing something like below would work nicely

<h1 :style="{ color: activeColor, fontSize: fontSize + 'px' }">Hello World</h1>

Nicely explained on official documentation.

But there is one problem here, what if you want to apply styles like :hover, :nth-child, :active, :focus etc ?  This solution will not work.

2. By adding <style> tag inside <template> tag

This method is actually wrong but for some reasons it worked for me on my local machine and then after deploying, it didn’t 😆

<template>
... other code ...
<style>
h1{ color: {{activeColor}}, fontSize: {{fontSize}}px }
</style>
</template>

Later I found that some people tried this method and got below warning:

Templates should only be responsible for mapping the state to the UI. Avoid placing tags with side-effects in your templates, such as , as they will not be parsed.

3. Using Dynamic component

VueJS has a nice feature to load components dynamically. Which mean you can simply write <component :is=”COMPONENT_NAME”> and the component with that name gets loaded. And we can make use of it to load <style> tag inside <template> tag. Something like this:

<template>
<h1>Hello World</h1>>

<component :is="'style'">
h1{ color: {{activeColor}}, fontSize: {{fontSize}}px }
</component>
</template>

Notice the :is=”‘style'”, here you can not write is=”style” directly as “is” always have to be bound to some component name. In our case style is inbuilt html component, so we are simply passign it as a string and not as a component.

This method worked for me without any errors. But there is no official statement about this if we should use it this way or not. I found this solution from Vuejs forum . Make note the solution given on forum doesn’t have the is bound which causes error. So :is should always be bound.

Comments