Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove fallbacks from theme var(...) calls #14881

Merged
merged 4 commits into from
Nov 5, 2024

Conversation

adamwathan
Copy link
Member

This PR changes how we render var(...) calls for theme values, removing the fallback values we were previously including.

  .text-white {
-   color: var(--color-white, #fff);
+   color: var(--color-white);
  }

We previously included the fallbacks only so you could see the value in dev tools but this feels like a bad reason to bloat the CSS. I'd rather just convince the Chrome team to surface this stuff better in dev tools in the first place.

@adamwathan adamwathan force-pushed the change/remove-var-fallbacks branch from 3c1874f to 9507b58 Compare November 5, 2024 20:28
@adamwathan adamwathan merged commit 7175605 into next Nov 5, 2024
1 check passed
@adamwathan adamwathan deleted the change/remove-var-fallbacks branch November 5, 2024 20:44
@kieranm
Copy link

kieranm commented Dec 9, 2024

@adamwathan Hey, I think this change has broken our theme.

Previously we had it defined like this:

--color-primary: oklch(var(--primary));
--color-on-primary: oklch(var(--on-primary));
 --color-background: oklch(var(--background));
 --color-surface: oklch(var(--surface));
 --color-elevated: oklch(var(--elevated));
...

Variables such as --surface vary depending on what classes are applied to a div. For example, the state success would set it to green, and state error would set it to red.

I don't fully understand why but this doesn't work any more but it worked fine when the fallback values were set. I think it's because Tailwind defines the colors at :root and when Chrome evaluates them, --surface is not defined (it can't look "down" the DOM, only up). The fallback meant that colours were defined explicitly next to each DOM element and so this wasn't a problem.

I think this change also breaks class-based dark mode when using this variable-based colour system, since the "dark" class is applied on (eg) body which is below :root and therefore it can't be evaluated properly. So you couldn't have --surface refer to different colors in light and dark mode.

At a bit of a loose end with this one, let me know if you have any ideas, thanks!

@kieranm
Copy link

kieranm commented Dec 9, 2024

I have managed a bit of an ugly workaround... manually redefining all the color CSS variables every time one of the inner variables (eg. --state) is used...

@utility state {
  @apply colors;
  ...

  .dark & {
    @apply ...
  }

  &.error {
    --hue: 22;
  }

  &.warning {
    --hue: 55;
  }

  &.success {
    --hue: 150;
  }

  &.info {
    --hue: 220;
  }
}

@utility colors {
  /* Copied and pasted from the theme */
  --color-transparent: transparent;
  --color-primary: oklch(var(--primary));
  --color-on-primary: oklch(var(--on-primary));
  --color-background: oklch(var(--background));
  --color-surface: oklch(var(--surface));
}

I've had to copy and paste from the theme because it doesn't look like it's possible to use @apply within a theme

@philipp-spiess
Copy link
Member

@kieranm We have the inline option you want to use for your usecase. It's necessary since otherwise the vars defined on the :root will never resolve to what you expect as you noticed. So what you want is to define the theme vars like this:

@theme inline {
  --color-primary: oklch(var(--primary));
  --color-on-primary: oklch(var(--on-primary));
  --color-background: oklch(var(--background));
  --color-surface: oklch(var(--surface));
  --color-elevated: oklch(var(--elevated));
}

There's some more info on this here: #15280 (comment)

We'll improve our documentation around this!

@kieranm
Copy link

kieranm commented Dec 10, 2024

Thanks @philipp-spiess will give that a go!

Is it possible/recommended to use @theme and @theme inline together? ie. only extract the colours into inline and leave the rest where they are?

@philipp-spiess
Copy link
Member

Is it possible/recommended to use @theme and @theme inline together? ie. only extract the colours into inline and leave the rest where they are?

@kieranm Yep that should work as you'd expect it to!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants