I am trying to build a way for a user to define the primary color of the website. When defining my tailwind classes, I want to use something like bg-primary-600
rather than hard coding a color, so that when the value for primary
changes, it will update the style.
Here I have my test environment: https://stackblitz.com/edit/nuxt-starter-qinx8e?file=tailwind.config.js
For those who don't want to open the link
tailwind.config.js
/** @type {import('tailwindcss').Config} */
const colors = require('tailwindcss/colors');
module.exports = {
darkMode: 'class',
content: [
'./components/**/*.{js,vue,ts}',
'./layouts/**/*.vue',
'./pages/**/*.vue',
'./plugins/**/*.{js,ts}',
'./nuxt.config.{js,ts}',
'./app.vue',
],
theme: {
extend: {
colors: {
// This should be changed by the user instead of hard coding
primary: colors.blue,
},
},
},
};
app.vue
<template>
<div>
<div >HELLO WORLD</div>
<div >HELLO WORLD</div>
<button @click="myColor = 'blue'">
Blue
</button>
<button @click="myColor = 'green'">
Green
</button>
<body >
My color is: {{ myColor }}
</body>
</div>
</template>
<script setup>
const myColor = ref('orange');
</script>
I cannot seem to figure out how to dynamically change the color in Tailwind. I'm able to hard code a value like in my example, but I cannot assign this value to a reactive variable and have it update.
I cannot figure out how to make the myColor ref update the color in tailwind. Note that I don't want to update it just in the page, I need to be able to update tailwind so that any reference to primary, regardless of the page or component will have the correct color.
CodePudding user response:
You can use CSS variables to achieve that
In your tailwind config, set primary as a CSS var:
theme: {
extend: {
colors: {
// This should be changed by the user instead of hard coding
primary: 'var(--color-primary)',
// This will extend functionality of your color
// so you can use opacity on it like text-secondary/80
// var has to have rgb in it not hex color like: --color-info: 14 165 233;
secondary: 'rgb(var(--color-secondary) / <alpha-value>)'
},
},
},
Then you can override the var in the app using style.setProperty
:
<template>
<div>
<div >HELLO WORLD</div>
<button @click="myColor = 'blue'">
Blue
</button>
<button @click="myColor = 'green'">
Blue
</button>
<body >
My color is: {{ myColor }}
</body>
</div>
</template>
<script setup>
import { ref, watch } from 'vue';
const colors = {
blue: '#0077FF',
green: '#00DD77',
};
const myColor = ref('orange');
watch(myColor, (color) => {
document.documentElement.style.setProperty('--color-primary', colors[color]);
});
</script>
<style>
:root {
--color-primary: #ff9900;
}
</style>
Note that tailwind will not be able to determine the color variations, so you cannot use bg-primary-500
or bg-primary-200
you need to drop the number i.e. bg-primary
and text-primary
etc.
CodePudding user response:
I figured out how to dynamically set the primary color and still maintain the ability to do things like bg-primary-600
. Now I just need to figure out how to make the user able to change this value, but that's a cookie issue not a tailwindcss issue.
I split up the export into separate blocks, so that I could dynamically define my theme block based on the value of a variable.
tailwind.config.js
/** @type {import('tailwindcss').Config} */
const colors = require('tailwindcss/colors');
const color = 'blue';
exports.darkMode = 'class';
exports.content = [
'./components/**/*.{js,vue,ts}',
'./layouts/**/*.vue',
'./pages/**/*.vue',
'./plugins/**/*.{js,ts}',
'./nuxt.config.{js,ts}',
'./app.vue',
];
if (color === 'blue') {
exports.theme = {
extend: {
colors: {
primary: colors.blue,
},
},
};
}
if (color === 'green') {
exports.theme = {
extend: {
colors: {
primary: colors.green,
},
},
};
}
if (color === 'orange') {
exports.theme = {
extend: {
colors: {
primary: colors.orange,
},
},
};
}