text-primary-500/50
not working as expected.
I have a color named primary
. This color doesn't have any specific settings; instead, I assign existing colors based on a template. If the parent element has the class theme-red
, the primary
color should essentially match the red
color. If the parent element has the class theme-blue
, the primary
color should match the blue
color. By default, the primary color is red.
I have implemented this in the following example.
tailwind.config = {
theme: {
extend: {
colors: {
primary: {
500: 'var(--color-primary-500)',
},
},
},
},
}
<script src="https://cdn.tailwindcss.com/3.4.5"></script>
<style type="text/tailwindcss">
@layer utilities {
.theme-red {
--color-primary-500: theme('colors.red.500');
}
.theme-blue {
--color-primary-500: theme('colors.blue.500');
}
}
</style>
<div>
<div class="text-green-500">
Default Green Color
</div>
<div class="text-green-500/50">
Default Green Color With Opacity
</div>
</div>
<!-- Not working examples with dynamic primary color -->
<div class="theme-red">
<div class="text-primary-500">
Example Red Theme
</div>
<div class="text-primary-500/50">
Example Red Theme With Opacity
</div>
</div>
<div class="theme-blue">
<div class="text-primary-500">
Example Blue Theme
</div>
<div class="text-primary-500/50">
Example Blue Theme With Opacity
</div>
</div>
The issue arises with transparent colors, such as text-primary-500/50
. That is, it should be text-primary-500
with 0.5 opacity. It doesn't work because text-primary-500
is essentially a hex color, but in CSS, we expected an RGB color code, which we could then blend with opacity on a 0-1 scale. How can I make it work so that text-primary-500/50
functions similarly to my written logic?
I expected primary color to work the same way as the base colors, as shown with the green color in the previous result. Here’s an example of what I would like.
You could consider using color-mix()
in your color definition. This allows the use of the Tailwind <alpha-value>
token to affect the transparency of a CSS variable that is not in HSL or RGB component format:
tailwind.config = {
theme: {
extend: {
colors: {
primary: {
500: 'color-mix(in srgb, var(--color-primary-500) calc(100% * <alpha-value>), transparent)',
},
},
},
},
}
<script src="https://cdn.tailwindcss.com/3.4.5"></script>
<style type="text/tailwindcss">
@layer utilities {
.theme-red {
--color-primary-500: theme('colors.red.500');
}
.theme-blue {
--color-primary-500: theme('colors.blue.500');
}
}
</style>
<div class="theme-red">
<div class="text-primary-500">
Example Red Theme
</div>
<div class="text-primary-500/50">
Example Red Theme With Opacity
</div>
</div>
<div class="theme-blue">
<div class="text-primary-500">
Example Blue Theme
</div>
<div class="text-primary-500/50">
Example Blue Theme With Opacity
</div>
</div>
Alternatively, you could consider revising the CSS variable definition to be inside a Tailwind plugin. This allows the values to be manipulated to HSL or RGB component format. Then, the <alpha-value>
token can be used more "natually" in a rgb()
or hsl()
CSS function:
tailwind.config = {
theme: {
extend: {
colors: {
primary: {
500: 'rgb(var(--color-primary-500) / <alpha-value>)',
},
},
},
},
plugins: [
tailwind.plugin(({ addBase, theme }) => {
const toRgb = (hex) => {
const r = parseInt(hex.substring(1, 3), 16);
const g = parseInt(hex.substring(3, 5), 16);
const b = parseInt(hex.substring(5, 7), 16);
return `${r} ${g} ${b}`;
};
addBase({
'.theme-red': {
'--color-primary-500': toRgb(theme('colors.red.500')),
},
'.theme-blue': {
'--color-primary-500': toRgb(theme('colors.blue.500')),
},
});
}),
],
}
<script src="https://cdn.tailwindcss.com/3.4.5"></script>
<div class="theme-red">
<div class="text-primary-500">
Example Red Theme
</div>
<div class="text-primary-500/50">
Example Red Theme With Opacity
</div>
</div>
<div class="theme-blue">
<div class="text-primary-500">
Example Blue Theme
</div>
<div class="text-primary-500/50">
Example Blue Theme With Opacity
</div>
</div>