3

In Angular we can dynamically set css properties, like this:

<style ng-if="color">
.theme-color { color: {{color}}; }
.theme-background-color { background-color: {{color}}; }
.theme-border-color { border-color: {{color}}; }
</style>

In Vue, we can modify :class=... but that limits us to predefined class options, and :style... that doesn't allow us to use class names.

Is there a way to achieve dynamic CSS as above? Or do we have to code the styles so that they include all color properties?

Thanks

1
  • What browsers do you need to support? You may be able to approach it with CSS variables. Commented Feb 24, 2018 at 16:39

2 Answers 2

2

Assuming this has some sort of user colour picking intervention; I would store the user's chosen colour in the state, so it's globally accessible.

Then within your component, you could do the following...

<app :style="themeStyles"></app>

export default {
  computed: {
    themeStyles () {
      return {
        color: store.state.themeColor,
        backgroundColor: store.state.themeColor,
        borderColor: store.state.themeColor
      }
    }
  }
}

(Pseudocode so to provide example quickly)

Obviously, use it on whatever component you need - but it should do the trick, so long as you have a way of storing user's input for the themeColor itself & store it in the state.

Edit: additional option

JSS

Sign up to request clarification or add additional context in comments.

2 Comments

This wouldn't work as smoothly as it seems it would.This is relying totally on the cascade. As soon as a color is set on a child that's the new color there downward.
@BillCriswell do you mean it won't win specificity wars? If so, you could add an !important.. I see you're point though, will have another think. You could possibly generate classes and assign their rules in computed, much in the same way listed above but with a different syntax/structure.
1

If you don't need Internet Explorer support you can use CSS variables.

Here's a quick CodeSandbox with an example: https://codesandbox.io/s/rr80o6kq3n

Here's the relevant code.

<template>
  <div class="foo">
    <div class="bar">Hello World</div>
  </div>
</template>

<style scoped>
.foo {
  --theme-color: black;
}

.bar {
  font-weight: bold;
  transition: color 0.2s;
  color: var(--theme-color);
}
</style>

<script>
export default {
  data () {
    return {
      hue: 0,
    }
  },

  watch: {
    hue (hue) {
      this.$el.style.setProperty(
        "--theme-color",
        `hsl(${hue % 360}, 100%, 50%)`,
      )
    },
  },

  mounted() {
    window.setInterval(() => {
      this.hue += 20
    }, 500)
  },
}
</script>

2 Comments

MSFT was my biggest customer for over twenty years. And I'm perfectly happy to ignore them - and NOT support the msft stack. ;) That said, I prefer to work within the Vue metaphor. But thank you for the good suggestion. :)
It just wouldn't work in IE <= 11. It would work fine in Edge.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.