tailwindcss icon indicating copy to clipboard operation
tailwindcss copied to clipboard

variable colors with <alpha-value> not working with theme function on plugins

Open gsmeira opened this issue 3 years ago • 5 comments

I'm trying to create a plugin for Tailwind 3.1.8, but when I use variables on colors with the new syntax - rgb(var(--primary) / <alpha-value>) - the color stop working.

I created an example on https://play.tailwindcss.com/2apCJBfHdC

Removing the / <alpha-value> from the color value make things work again.

I'm doing something wrong?

gsmeira avatar Aug 19 '22 19:08 gsmeira

Looks like a PR was opened about this in the past but somehow the behaviour isn't working anymore. https://github.com/tailwindlabs/tailwindcss/pull/8652

~Related, it would be nice to be able to overwrite the <alpha-value> when using theme(), which I don't believe is possible currently.~ Looks like that is possible. https://github.com/tailwindlabs/tailwindcss/pull/9008

Kosai106 avatar Aug 27 '22 11:08 Kosai106

I hate to be the one doing this but is there any updates on this @thecrypticace?

Kosai106 avatar Oct 20 '22 14:10 Kosai106

No worries! Sorry for the late reply. We have been thinking this through some but other things took priority for the v3.2 release.

The reason it doesn't work for plugins like this is two fold:

  1. addUtilities doesn't do anything fancy like parsing data types. It's basically to put pure CSS into the stylesheet whenever a utility is used (and it can handle variants ofc)
  2. matchUtilities does parse data types and it takes a type option that lists all acceptable "types" for a plugin — as well as a list of values. You get the <alpha-value> behavior for "free" when using it and your type list includes color.

For example, this works today: https://play.tailwindcss.com/1a6LIjNR2S?file=config — Except for the DEFAULT case + opacity modifier which I believe is a bug but I'll have to check on that. However, we're also thinking through what we want to work here.

I think that in an ideal world each plugin would take in the opacity and modify the color itself (or we provide a function to do this for you — not sure though). And we could remove this special case for the color type. We're going to try to dedicate some time soon-ish to figuring out how this should work at a high level for plugin authors to see if:

  1. The existing matchUtilities API / workaround is what we want; OR
  2. If there's a better, more automatic API that we can design and implement.

thecrypticace avatar Oct 20 '22 15:10 thecrypticace

:root, [data-theme="default"] { // main --color-primary-darker: hsl(220, 90%, 36%); --color-primary-dark: hsl(220, 90%, 46%); --color-primary: hsl(220, 90%, 56%); --color-primary-light: hsl(220, 90%, 66%); --color-primary-lighter: hsl(220, 90%, 76%); --color-primary-a20: hsla(220, 90%, 56%, 0.2);

--color-accent-darker: hsl(355, 90%, 41%); --color-accent-dark: hsl(355, 90%, 51%); --color-accent: hsl(355, 90%, 61%); --color-accent-light: hsl(355, 90%, 71%); --color-accent-lighter: hsl(355, 90%, 81%);

// color contrast --color-bg: hsl(0, 0%, 100%); --color-bg-a00: hsla(0, 0%, 100%, 0); --color-contrast-lower: hsl(0, 0%, 95%); --color-contrast-low: hsl(240, 1%, 83%); --color-contrast-medium: hsl(240, 1%, 48%); --color-contrast-high: hsl(240, 4%, 20%); --color-contrast-higher: hsl(240, 8%, 12%); --color-contrast-higher-a90: hsla(240, 8%, 12%, 0.9);

// semantic --color-border: var(--color-contrast-low); GTA Portal

Jakeduncan00 avatar Dec 27 '22 10:12 Jakeduncan00

In the Library that I've created which is RippleUI, I encountered with this same issue, I created a function to apply the opacity and then when some color is called, the function will trigger and if the user specifies a opacity will go there

Definition of variables in this example https://github.com/Siumauricio/rippleui/blob/main/config/theme/var-theme.ts#L12

The function when a user call some color https://github.com/Siumauricio/rippleui/blob/main/config/utils/applyOpacityValue.ts#L1

Siumauricio avatar Jan 12 '23 20:01 Siumauricio

@thecrypticace

hey 👋

I was trying to add a matchUtilities function today to automatically create some utilities from a user-defined set of colors.

I'm using this configuration as explained by you above, but can't seem to get it working like in your example:

plugin(({ matchUtilities, theme }) => {
  matchUtilities(
    {
      foo: (value) => ({ backgroundColor: value }),
    },
    {
      type: ['color'],
      values: theme('colors')
    }
  )
})

The generated CSS looks like this:

background-color: ({ opacityValue =1 })=>oldValue.replace("<alpha-value>", opacityValue) !important;

I tried to rename the property from backgroundColor to color which resulted in the same result.
Trying to call value as a function (value()) seems to kinda work, but results in the following error: TypeError: Cannot read property 'opacityValue' of undefined

I'm using Tailwind CSS v3.2.6.

Can you point me in the right direction?

timkley avatar Feb 14 '23 15:02 timkley

It's not working on the class either: https://play.tailwindcss.com/qLbGj1TFv7

We can't apply opacity when using var(--something)

edit: workaround is to apply alpha with hex color: #00000080 for 50% i.e.

karimhossenbux avatar Apr 02 '23 13:04 karimhossenbux

@karimhossenbux The reason you can't apply an opacity to var(--something) is because the colorspace is defined at runtime. What you want is to say bg-[rgba(var(--something))] and not bg-[var(--something)]. Only the 2nd of which can be written in the shorthand bg-[--something].

Until very very recently there has been no way in browsers to augment any arbitrary color and give it an alpha channel.

The only two ways to do this are:

  1. Using color-mix() to mix a color with transparent — which multiplies the alpha value.
  2. Relative color syntax which can replace a color's alpha channel. You have to make sure to use a color space with a wide gamut in case the source color is also a wide gamut color.

And, unfortunately — at least as of right now — none of those are 100% implemented across all browsers — though I think things have gotten close-ish in just the past 3ish months. Can I Use unfortunately doesn't have up-to-date data at the moment.

thecrypticace avatar Apr 03 '23 03:04 thecrypticace

Same issue here.

Extending the theme colors won't work.

module.exports = {
    darkMode: 'class',
    content: ['./index.html', './src/**/*.{vue,js,ts,jsx,tsx}'],
    theme: {
        extend: {
            colors: {
                'my-blue': 'rgb(var(--my-color-black) / <alpha-value>)',
            },
        },
    },
    plugins: [],
};

re2005 avatar Apr 11 '23 17:04 re2005

var(--my-color-black) / <alpha-value>

Just wanted to comment also experiencing the same problem as re2005 extending the theme alpha-value is not being parsed properly.

As the docs suggest it should work in the CSS variables section https://tailwindcss.com/docs/customizing-colors#using-css-variables

KrisCoulson avatar May 01 '23 18:05 KrisCoulson

This works for me. It was covered in the opacity section of this video https://www.youtube.com/watch?v=MAtaT8BZEAo

It seems like the docs don't mention this anywhere?

https://play.tailwindcss.com/oYulJ30B14?file=config

austinm911 avatar May 22 '23 00:05 austinm911

Hey @austinm911 thanks for the example, the problem is that we are trying to set alpha on custom colors.

re2005 avatar May 22 '23 07:05 re2005

After little more investigation was very clear how to make it work.

First you need to declare your color variable using RGB and not HEX

On your css config:

$blue: 56, 114, 221;

@layer base {
    :root {
        --my-color-blue: #{$blue};
    }
}

On tailwind config

module.exports = {
    theme: {
        extend: {
            colors: {
                'my-color-blue': 'rgb(var(--my-color-blue), <alpha-value>)',
            },
        },
    },
    plugins: [],
};

Usage:

<div class="bg-my-color-blue bg-opacity-20">
    Bingo!
</div>

re2005 avatar May 22 '23 07:05 re2005

Something that might be valuable. I’ve found that theme('colors.primary.DEFAULT / 1') still works when configuring Tailwind Typography variables, but not JS based custom plugin configurations. If anyone found a workaround I’d love to learn.

robdekort avatar Jun 06 '23 20:06 robdekort

Same issues, extend color cannot use opacity. ex bg-primary/20 or bg-primary bg-opacity-20. its not work

kydner avatar Aug 11 '23 01:08 kydner

interestingly, theme(), "theme()" and @apply will all generate different values:

see https://play.tailwindcss.com/fX0CEoXvGu

addUtilities({
  '.test': {
    color: theme('colors.primary.DEFAULT'),
    background: 'theme("colors.primary.DEFAULT")',
    '@apply border-primary': '',
  },
})

will generate:

.test {
    color: rgb(var(--primary) / <alpha-value>);
    background: rgb(var(--primary) / 1);
    --tw-border-opacity: 1;
    border-color: rgb(var(--primary) / var(--tw-border-opacity));
}

looks like only @apply does the correct thing currently?

stefanprobst avatar Aug 18 '23 20:08 stefanprobst

@stefanprobst Wow, @apply in the TW config file does actually work. 🤯 Should it though? Thanks for the tip btw!

robdekort avatar Sep 12 '23 18:09 robdekort

The docs for HSL are incorrect

  // Using modern `hsl`
      primary: 'hsl(var(--color-primary) / <alpha-value>)',
      secondary: 'hsl(var(--color-secondary) / <alpha-value>)',

should be

  // Using modern `hsl`
      primary: 'hsl(var(--color-primary), <alpha-value>)',
      secondary: 'hsl(var(--color-secondary), <alpha-value>)',

Pagebakers avatar Nov 08 '23 15:11 Pagebakers

@Pagebakers that is incorrect. The example is using the correct "modern" CSS syntax.

See example here: https://play.tailwindcss.com/rFbKXTknA2 And the CSS spec: https://www.w3.org/TR/css-color-4/#the-hsl-notation

thecrypticace avatar Nov 08 '23 15:11 thecrypticace

I've stumbled on the same problem in my current project, I've defined some theme colors: white: 'oklch(100% 0 0 / <alpha-value>)'

And when I reference these colors to attach them to a css variable like so: '--color-theme-contrast': theme('colors.white')

It get's outputted like so in the css: --color-theme-contrast: oklch(100% 0 0 / <alpha-value>);

Very frustrating because my current project depends on those css variables, otherwise i'm stuck for the foreseeable future. It would be nice if I could just target the actual value of the color, so that it just outputs 100% 0 0

kobe-f8 avatar Nov 15 '23 15:11 kobe-f8

this issue has been open for more than half and a year now. when will this issue be fixed?

mominshaikhdevs avatar Nov 15 '23 18:11 mominshaikhdevs

This a working version of your example

https://play.tailwindcss.com/e0JLQ1XNqB

safwanolaimat avatar Nov 27 '23 04:11 safwanolaimat

colors: {
  primary: 'rgb(var(--color-primary) / <alpha-value>)',
}

So using "theme('colors.primary')" instead of theme('colors.primary') seems to do the trick. Nice 👍

marcorieser avatar Dec 11 '23 10:12 marcorieser

interestingly, theme(), "theme()" and @apply will all generate different values:

see https://play.tailwindcss.com/fX0CEoXvGu

addUtilities({
  '.test': {
    color: theme('colors.primary.DEFAULT'),
    background: 'theme("colors.primary.DEFAULT")',
    '@apply border-primary': '',
  },
})

will generate:

.test {
    color: rgb(var(--primary) / <alpha-value>);
    background: rgb(var(--primary) / 1);
    --tw-border-opacity: 1;
    border-color: rgb(var(--primary) / var(--tw-border-opacity));
}

looks like only @apply does the correct thing currently?

I ran into this issue today and this is fixed it for me. Thanks so much @stefanprobst !

enzocomics avatar Dec 16 '23 20:12 enzocomics

Anyone was able to create a workaround when dealing with hex vars?

sandros94 avatar Jan 05 '24 15:01 sandros94

You can use hex or any color format you want if you use color-mix.

colors: {
  primary: `color-mix(
    in srgb,
    var(--primary-color-in-hex),
    transparent calc(100% - 100% * <alpha-value>)
  )`
}

You can make it much less wordy with a simple function like:

const colorMixAlphaValueWithCustomProperty = customPropertyName => `color-mix(
  in srgb,
  var(${customPropertyName}),
  transparent calc(100% - 100% * <alpha-value>)
)`

/*
colors: {
  primary: colorMixAlphaValueWithCustomProperty('--primary-color-in-hex')
  secondary: colorMixAlphaValueWithCustomProperty('--secondary-color-in-hex')
}
*/

A sample play: https://play.tailwindcss.com/PLN66o7PtF?file=config

crswll avatar Jan 05 '24 15:01 crswll

@crswll thank you very much, but I just realized it was even simpler and decided to open up a PR for a doc example:

// tailwind.config.js
module.exports = {
  theme: {
    colors: {
      // For --color-primary: #ff73b3
      primary: 'rgb(from var(--color-primary) r g b / <alpha-value>)',
    }
  }
}

sandros94 avatar Jan 05 '24 16:01 sandros94

No problem. The browser support for Firefox is not there for that, though.

crswll avatar Jan 05 '24 16:01 crswll

No problem. The browser support for Firefox is not there for that, though.

do you have a link to share? I was looking for it right now

sandros94 avatar Jan 05 '24 16:01 sandros94

https://caniuse.com/css-relative-colors

crswll avatar Jan 05 '24 16:01 crswll