tailwindcss icon indicating copy to clipboard operation
tailwindcss copied to clipboard

oklch color definitions don't work with color/opacity syntax — classes missing or incomplete

Open andronocean opened this issue 1 year ago • 4 comments

What version of Tailwind CSS are you using?

v3.4.13

What build tool (or framework if it abstracts the build tool) are you using?

Tested with Bud.js 6.23.3 (using postcss 8.4.24) and Tailwind Playground.

What version of Node.js are you using?

v20.16.0

What browser are you using?

N/A

What operating system are you using?

macOS Sonoma 14.7

Reproduction URL https://play.tailwindcss.com/dDmsole8X3

Describe your issue

When colors are added to a Tailwind config using the standard oklch() function, the resulting color classes do not work with Tailwind's methods of controlling opacity. For a color like primary: "oklch(68% 0.15 237.33)", these two issues appear:

  1. The simple color classes generated are missing the opacity properties like var(--tw-bg-opacity) and var(--tw-text-opacity) — it seems that Tailwind just copies the value directly.
  2. Tailwind completely fails to generate modified-opacity classes for these colors, like bg-primary/50.

The same problems occur if I explicitly declare an opacity in the color definition: primary: "oklch(68% 0.15 237.33 / 1)".

Classes ARE generated correctly if I use the <alpha-value> placeholder in color definitions: primary: "oklch(68% 0.15 237.33 / <alpha-value>)". However, this magic is not explained anywhere in Tailwind's color documentation: https://tailwindcss.com/docs/customizing-colors

The playground link shows both issues and contrasts the correct behavior of colors defined using rgb(r g b / a) notation.

andronocean avatar Sep 23 '24 20:09 andronocean

Getting the same issue v3.4.14

JordanKnipe avatar Oct 17 '24 05:10 JordanKnipe

They seem to have removed <alpha-value> mentions from the docs like a month ago: https://github.com/tailwindlabs/tailwindcss.com/pull/1868/files

How can you allow for OKLCH to get the opacity modifier without it?

I have this working with it:

/* globals.css */
@layer base {
  :root {
    /* ... */
    --color-copperfield-500: 58.08% 0.1679 34.86; /* #d86237 */
    /* ... */
  }
}

And in config

// tailwind.config.ts
const config = {
  theme: {
    extend: {
      colors: {
        copperfield: {
          // ...
          500: "oklch(var(--color-copperfield-500) / <alpha-value>)",
          // ...
        },
      },
  },
}

edit: now also found this comment https://github.com/tailwindlabs/tailwindcss/issues/9143#issuecomment-1946755547

MartinCura avatar Oct 17 '24 12:10 MartinCura

I ended up defining the base, no-alpha colors in a separate module that I export:

// palette.ts
const palette = {
  ocean: {
    100: "oklch(91.65% 0.047 237)",
    // ...
  }
}

Then in my Tailwind config I pass them through a closure to add the <alpha-value>:

// tailwind.config.ts
import { palette } from 'palette';

const addAlphaChannelForTailwind = (color: string) => {
  const chars = Array.from(color);
  // insert the placeholder just before closing ')'
  chars.splice( chars.lastIndexOf(')'), 0, '/ <alpha-value>'  );
  return chars.join('');
}

export default {
  theme: {
    colors: {
      ocean: {
        100: addAlphaChannelForTailwind(palette.ocean['100']),
        // ...
      }
    }
  }
}

(actual code uses a second function to loop through the defined shades and add all of them at once to the Tailwind object, for less repetition).

The reason to avoid a custom property in the Tailwind definition is that postcss-preset-env (or the like) cannot create rgba() fallback values for older browsers that don't support oklch(), since it cannot resolve the var(--color) at build time.

I also don't like using custom properties for the contents of a color function and not the actual color — it makes for bad transitions and animations, and doesn't work with the CSS Properties and Values API.

And the hack using color-mix()browser support for that is worse than oklch(), and you again have a problem with postcss-preset-env not being able to generate fallbacks.

The way I've done it, all the classes work, I can refer to the colors from my own CSS in the usual ways (for instance making custom properties there: --ocean-100: theme('colors.ocean.100');), and fallback colors are generated everywhere as they should be.

andronocean avatar Oct 17 '24 17:10 andronocean

it seams like v3 only parse rgb/hsl for opacity, https://github.com/tailwindlabs/tailwindcss/blob/6069a811871c58a9b202fbb3a6f13774c57278c0/src/util/color.js#L47 it would be nice to add support for oklch

RyanYANG52 avatar Dec 02 '24 01:12 RyanYANG52

https://github.com/tailwindlabs/tailwindcss/pull/15293

RyanYANG52 avatar Dec 04 '24 03:12 RyanYANG52

Hey! I saw that @RobinMalfait responded to your PR but this issue was still left open: https://github.com/tailwindlabs/tailwindcss/pull/15293#issuecomment-2618905076

With v4 being out with much better support for oklch(…) colors, I'm definitely agreeing that this is not something that we'll likely going to change in v3 anymore. Thanks for your understanding.

philipp-spiess avatar Apr 11 '25 10:04 philipp-spiess