tailwindcss icon indicating copy to clipboard operation
tailwindcss copied to clipboard

[v4] transition-property Theme CSS Variables

Open mshimokura opened this issue 9 months ago • 4 comments

What version of Tailwind CSS are you using?

v4.0.6

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

Next.js: 15.1.3

What version of Node.js are you using?

v20.18.1

What browser are you using?

Safari

What operating system are you using?

macOS

Reproduction URL

https://play.tailwindcss.com/pNcjYumxXW

Describe your issue

Overview

I am trying to migrate a project to v4, which has custom transition properties defined in the config.

Previously:

// tailwind.config.ts
theme: { extend: { transitionProperty: { ring: 'box-shadow' } } }

// component.tsx
<input className="transition-[theme(transitionProperty.colors),theme(transitionProperty.ring)]" />

Expected migration:

// globals.css
@theme {
  --transition-property-ring: box-shadow;
}

// component.tsx
<input className="transition-[theme(--transition-property-colors),theme(transition-property-ring)]" />

Specifics

The included transition properties are not included as css variables (i.e. theme(--transition-property-colors) does not work), but it does work with the old syntax, i.e. theme(transitionProperty.colors).

Similar to the previous report in #14479, using the default transition properties (i.e. transition-colors) does not output css variables.

Also, for example, --transition-property-ring: box-shadow does work in the @theme declaration but it is not documented (afaict). If you would like this raised as a separate documentation issue I can do that, but I think that it may change based on how the default transition properties are implemented (i.e. should they also be css variables in the documentation?)

mshimokura avatar Feb 18 '25 19:02 mshimokura

Hey! So the reason for this is that we no longer have the default transition property list as CSS variables as we realized nobody was really changing the defaults here besides maybe adding new presets (which is still supported). Because of the backward compatibility though, the old syntax (transitionProperty.colors) will still work for now but since these aren't CSS vars, the new syntax won't right now.

What you can do for now is to create other named transition properties that contain the mixture of properties that you are often using in your app, e.g.:

@theme {
  --transition-property-ring: box-shadow;
  --transition-property-ring-color: box-shadow, color, background-color, border-color, outline-color, text-decoration-color, fill, stroke, --tw-gradient-from, --tw-gradient-via, --tw-gradient-to;
}

This way you can just use transition-ring and transition-ring-colors and don't have to worry about what is present as a CSS variable and not (You can find the other defaults here: https://github.com/tailwindlabs/tailwindcss/blob/main/packages/tailwindcss/src/utilities.ts#L3594-L3601)

Going to leave this open so we have time to think over this a bit though, thanks!

philipp-spiess avatar Feb 19 '25 10:02 philipp-spiess

Thanks for the response & consideration!

I can certainly appreciate that these are 'special' values that perhaps don't really belong in the "theme" (since nobody would really change them), and I do appreciate that they're still extensible.

However, I think that if the theme() function is really supposed to "evolve" to the new version, then they should be made available that way. Or perhaps they belong in some new class of "static" css variables, or accessible via some sort of static function instead?

I do think though, given that you can extend them by editing the @theme directive, they should be elevated to true theme status for consistency.

One other thought that I had, was that the transition-colors utility also changed to include outline-color and perhaps if someone wanted to customize their theme to revert that, then that might be supported if transition-property was changed to be a first-class theme property & transition's default also used those theme css variables.

For example in this playground, we can override transition-colors but it outputs two css classes, and transition (default) does not take into account that transition-colors was overriden: https://play.tailwindcss.com/tNvFvk7pR1

  @theme {
    --transition-property-colors: color, background-color, border-color, text-decoration-color, fill, stroke, --tw-gradient-from, --tw-gradient-via, --tw-gradient-to;
  }
  /* ... */
  .transition-colors {
    transition-property: color, background-color, border-color, outline-color, text-decoration-color, fill, stroke, --tw-gradient-from, --tw-gradient-via, --tw-gradient-to;
    transition-timing-function: var(--tw-ease, var(--default-transition-timing-function));
    transition-duration: var(--tw-duration, var(--default-transition-duration));
  }
  .transition-colors {
    transition-property: var(--transition-property-colors);
    transition-timing-function: var(--tw-ease, var(--default-transition-timing-function));
    transition-duration: var(--tw-duration, var(--default-transition-duration));
  }

mshimokura avatar Feb 19 '25 14:02 mshimokura

nobody was really changing the defaults here

As one of the nobodies who changed the defaults to include @property's for --tw-gradient-from-position and friends, it would be really nice to have any way at all to configure these.

cofl avatar Feb 21 '25 18:02 cofl

I change the default transition property value on most of my projects. It would be great to have a way to custumize it via @theme.

nicolas-cusan avatar Apr 07 '25 17:04 nicolas-cusan

Heya! I just landed a PR that allows you to overwrite the default static transitoin properties with custom theme variables. If you do that, they will be emitted as vars again and you will be able to combine them in the same way you did with v3!

@theme {
  --transition-property-ring: box-shadow;
  --transition-property-ring-color: box-shadow, color, background-color, border-color, outline-color, text-decoration-color, fill, stroke, --tw-gradient-from, --tw-gradient-via, --tw-gradient-to;
}

philipp-spiess avatar Sep 11 '25 10:09 philipp-spiess

hey @philipp-spiess - nice work on completing the change to the default theme variables. However, I think the core of my issue is really around a "tailwind 4" solution to referencing the default theme variables for something like transition property - which is not actually a css variable to begin with.

I'm still interested in some version of this class working without the deprecated theme() function:

transition-[var(--transition-property-colors),var(--transition-property-ring)]

mshimokura avatar Sep 11 '25 17:09 mshimokura

@mshimokura Yeah I understand that but with the change I linked above, you can make the transition properties CSS variables in user space and then you can combine them like you're suggesting: https://play.tailwindcss.com/2meTEVgXpX?file=css

It's unlikely we're going to change the default here though. It'd be a breaking change (see https://github.com/tailwindlabs/tailwindcss/pull/17002#issuecomment-2704804919) and there hasn't been a lot of requests for it.

Hope this still works for you!

philipp-spiess avatar Sep 12 '25 09:09 philipp-spiess

@philipp-spiess

It'd be a breaking change (see https://github.com/tailwindlabs/tailwindcss/pull/17002#issuecomment-2704804919) and there hasn't been a lot of requests for it.

ah, gotcha on this point, however doesn't this mean that the theme() function should not be deprecated - if it's the only way to reference the default values for transition properties (or others like rounded-full?)

maybe something to consider for v5? is theme() truly deprecated, if so then there should be some plan for its eventual removal.

  • maybe a new function, something like defaultTheme(--rounded-full)
  • a new way of unsetting/resetting the theme variables like --*: unset; --intrinsics-*: initial; where each rule resolves to something like border-radius: var(--rounded-full, var(--intrinsics-rounded-full))

mshimokura avatar Sep 12 '25 12:09 mshimokura