You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Add support for inline option when defining @theme values (#14095)
This PR adds support for a new `inline` option when defining a `@theme`
block that tells Tailwind to use raw theme values for utilities instead
of referencing the corresponding generated CSS variable.
```css
/* Input */
@theme inline {
--color-red-500: #ef4444;
/* ... */
}
/* Example output */
:root {
--color-red-500: #ef4444;
}
.text-red-500 {
color: #ef4444;
}
```
This can be composed with the existing `reference` option in case you
want to define a `@theme` block as both `reference` (so the variables
aren't generated) and `inline`:
```css
/* Input */
@theme inline reference {
--color-red-500: #ef4444;
/* ... */
}
/* Example output */
.text-red-500 {
color: #ef4444;
}
```
Since you can have multiple `@theme` blocks, you can even define some
values normally and some as inline based on how you're using them. For
example you might want to use `inline` for defining literal tokens like
`--color-red-500`, but include the variable for tokens that you want to
be able to theme like `--color-primary`:
```css
/* Input */
@theme inline {
--color-red-500: #ef4444;
/* ... */
}
@theme {
--color-primary: var(--color-red-500);
}
/* Example output */
:root {
--color-red-500: #ef4444;
--color-primary: var(--color-red-500);
}
.text-red-500 {
color: #ef4444;
}
.text-primary {
color: var(--color-primary, var(--color-red-500));
}
```
## Breaking changes
Prior to this PR, you could `@import` a stylesheet that contained
`@theme` blocks as reference by adding the `reference` keyword to your
import:
```css
@import "./my-theme.css" reference;
```
Now that `reference` isn't the only possible option when declaring your
`@theme`, this syntax has changed to a new `theme(…)` function that
accepts `reference` and `inline` as potential space-separated values:
```css
@import "./my-theme.css";
@import "./my-theme.css" theme(reference);
@import "./my-theme.css" theme(inline);
@import "./my-theme.css" theme(reference inline);
```
If you are using the `@import … reference` option with an earlier alpha
release, you'll need to update your code to `@import … theme(reference)`
once this PR lands in a release.
## Motivation
This PR is designed to solve an issue pointed out in #14091.
Prior to this PR, generated utilities would always reference variables
directly, with the raw value as a fallback:
```css
/* Input */
@theme {
--color-red-500: #ef4444;
/* ... */
}
/* Example output */
:root {
--color-red-500: #ef4444;
}
.text-red-500 {
color: var(--color-red-500, #ef4444);
}
```
But this can create issues with variables resolving to an unexpected
value when a theme value is referencing another variable defined on
`:root`.
For example, say you have a CSS file like this:
```css
:root, .light {
--text-fg: #000;
}
.dark {
--text-fg: #fff;
}
@theme {
--color-fg: var(--text-fg);
}
```
Without `@theme inline`, we'd generate this output if you used the
`text-fg` utility:
```css
:root, .light {
--text-fg: #000;
}
.dark {
--text-fg: #fff;
}
:root {
--color-fg: var(--text-fg);
}
.text-fg {
color: var(--color-fg, var(--text-fg));
}
```
Now if you wrote this HTML, you're probably expecting your text to be
the dark mode color:
```html
<div class="dark">
<h1 class="text-fg">Hello world</h1>
</div>
```
But you'd actually get the light mode color because of this rule:
```css
:root {
--color-fg: var(--text-fg);
}
.text-fg {
color: var(--color-fg, var(--text-fg));
}
```
The browser will try to resolve the `--color-fg` variable, which is
defined on `:root`. When it tries to resolve the value, _it uses the
value of `var(--text-fg)` as it would resolve at `:root`_, not what it
would resolve to based on the element that has the `text-fg` class.
So `var(--color-fg)` resolves to `#000` because `var(--text-fg)`
resolved to `#000` at the point in the tree where the browser resolved
the value of `var(--color-fg)`.
By using `@theme inline`, the `.text-fg` class looks like this:
```css
.text-fg {
color: var(--text-fg);
}
```
With this definition, the browser doesn't try to resolve `--color-fg` at
all and instead resolves `--text-fg` directly which correctly resolves
to `#fff` as expected.
---------
Co-authored-by: Adam Wathan <4323180+adamwathan@users.noreply.github.com>
Co-authored-by: Robin Malfait <malfait.robin@gmail.com>
0 commit comments