Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
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 <[email protected]> Co-authored-by: Robin Malfait <[email protected]>
- Loading branch information