Using custom theming in Vuetify and pass color variables to components

Vuejs2Vue Componentvuetify.js

Vuejs2 Problem Overview


In my index.js file I have manually override the Vuetify theme object with my company's color:

Vue.use(Vuetify, {
  theme: {
    primary: '#377ef9',
    secondary: '#1b3e70',
    accent: '#ff643d',
    error: '#ff643d'
    ...
  }

Now, I can use these colors from my templates like so:

<my-text-field name="input text"
    label="text"
    value="text text text text..."
    type="text"
    color="primary">
</my-text-field>

What I'm after is using the primary or any other variable in the theme object defined above, inside my template style:

<script>
  import { VTextField } from 'vuetify'
  export default {
    extends: VTextField
  }
</script>

<style scoped lang="stylus">
  label
    color: <seconday color> <-- this is what I'm after
    color: #1b3e70 <-- this works, but not quite good enough for me
</style>

I can easily just write the hex value of my colors in the style section, but I don't want to repeat myself, and would rather use my theme object so it will also be easier for my to easily change the colors everywhere, and avoid typos which will lead to mistakes in the colors definitions.

Vuejs2 Solutions


Solution 1 - Vuejs2

Edit (2018/10/11)

Since version 1.2. we can enable CSS variables
NOTE: allegedly it won't work in IE (Edge should work), and possibly some Safari versions?

From docs (see Custom Properties)

> Enabling customProperties will also generate a css variable for each > theme color, which you can then use in your components'

For custom values e.g.
yourcustomvariablename: '#607D8B'
use --v-yourcustomvariablename-base (so base is default).



Original answer:

There is a Feature Request on github: Access theme colors in stylus files

@KaelWD (one of devs) wrote:

> This is something you'll have to implement yourself. I've tried doing > something similar before but it doesn't really work on a framework > level.

Issue is labeled wontfix


Edit (2018/10/11)
Also see this updated thread:
https://github.com/vuetifyjs/vuetify/issues/827 (Feature request: Native css variables)

Solution 2 - Vuejs2

There is a way to go around this by utilizing :style attributes. It can be used to set custom CSS properties reactively.

Add a computed property:

computed: {
    cssProps () {
        return {
            '--secondary-color': this.$vuetify.theme.secondary
        }
    }

Bind style to cssProps:

<div id="app" :style="cssProps">

Then, in your style:

<style scoped>
    label
        color: var(--secondary-color);
</style>

Adapted from this discussion: https://github.com/vuejs/vue/issues/7346

Solution 3 - Vuejs2

For anyone stumbling over this from Vuetify V2 onwards, you can do the following to get access to the SCSS colour variables.

// Import the Vuetify styles somewhere global
@import '~vuetify/src/styles/styles.sass';

// Now in your components you can access the colour variables using map-get
div {
  background: map-get($grey, lighten-4);
}

All the colours can be found in /node_modules/vuetify/styles/settings/_colors.scss.

Solution 4 - Vuejs2

From above answers, if you want to include all vuetify colors, put this code in App.vue template

<v-app :style="cssProps">

App.vue script

computed: {
   cssProps () {
      var themeColors = {}
      Object.keys(this.$vuetify.theme.themes.light).forEach((color) => {
        themeColors[`--v-${color}`] = this.$vuetify.theme.themes.light[color]
      })
      return themeColors
   }
}

Let say if you have this color in vuetify.js

export default new Vuetify({
  treeShake: true,
    theme: {
      themes: {
        light: {
          darkRed: "#CD3300",
        }
      }
    }
})

Then, in any component:

<style scoped>
  .label {
    color: var(--v-darkRed);
  }
</style>

Solution 5 - Vuejs2

Example of switching theme (helpfull link):

    <v-app :dark="setTheme" 
           :style="{background: $vuetify.theme.themes[theme].background}" 
           >

JS:

      computed: {
            setTheme() {
                this.$vuetify.theme.dark = this.goDark;
            }
      },
      data() {
            return { 
                goDark: false
            }
      }

Solution 6 - Vuejs2

Maybe I am late the most efficient way to do is as mentioned in the docs https://vuetifyjs.com/en/features/theme/#custom-properties

I will provide a working example for the same. you need only three changes to be done for this to get working.

  1. Mention the option which does the magic and your theme color
export default new Vuetify({
    theme: {
        options: {
            customProperties: true
        },
        themes: {
            light: {
                primary: "#3DCFD3",
                secondary: "#171b34",
                accent: "3D87E4"
            }
        }
    }
});
  1. Mention the class name in the tag where you want your theme to get applied
<h4 class="blue-header">Yash Oswal</h4>  
  1. CSS to apply your theme.
<style lang="scss">

.blue-header {
  color: var(--v-primary-base);
}

</style>

Solution 7 - Vuejs2

For vutify 3+: inside vuetify.js file declare theme color variable colors:{green:'#00ff00'}

// src/plugins/vuetify.js
import { createApp } from 'vue'
import { createVuetify } from 'vuetify'

export default createVuetify({
  theme: {
    defaultTheme: 'myCustomTheme',
    themes: {
      myCustomTheme: {
        dark: false,
        colors: {
          ..., // We have omitted the standard color properties here to emphasize the custom one that we've added
          green: '#00ff00'
        }
      }
    }
  }
})

inside .vue component file use rgb(var(--v-theme-green)):

<template>
  <div class="bg-green on-green">background color with appropriate text color contrast</div>

  <div class="text-green">text color</div>

  <div class="border-green">border color</div>
</template>

<style>
  .custom-class {
    background: rgb(var(--v-theme-green))
    color: rgba(var(--v-theme-on-green), 0.9)
  }
</style>

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionNarxxView Question on Stackoverflow
Solution 1 - Vuejs2TraxoView Answer on Stackoverflow
Solution 2 - Vuejs2VicView Answer on Stackoverflow
Solution 3 - Vuejs2Alex McCabeView Answer on Stackoverflow
Solution 4 - Vuejs2wanjijulView Answer on Stackoverflow
Solution 5 - Vuejs2Dmitry KaltovichView Answer on Stackoverflow
Solution 6 - Vuejs2N3XTView Answer on Stackoverflow
Solution 7 - Vuejs2RRRView Answer on Stackoverflow