Now that Tailwind CSS v4 is released, we can setup a proper release
workflow again. This setup mimics the workflow of how we did it in v3,
but adjusted to make it work on the v4 codebase.
Whenever a PR is merged into the `next` branch, we will publish an
insiders release to npm using the following version number:
`0.0.0-insiders.<commit-hash>`. Note: insiders releases will not have a
GitHub release associated with them, therefore the `standalone-cli`
won't be available as an insiders release.
For the normal release procedure, the following steps are required:
1. Manually version the packages (e.g.: `pnpm run version-packages`)
2. Create a git tag for the version you want to release
3. Push the updated package.json files and the git tag to the repository
Next, a GitHub action will kick in once a `tag` is being pushed.
The GitHub action will run a build, and create a draft release on GitHub
that will contain:
1. The CHANGELOG.md contents for the last version
2. The `standalone-cli` artifacts attached to the drafted release
Once you are happy with the draft, you can publish the draft on GitHub.
This in turn will trigger another GitHub action that will publish the
packages to npm.
Whenever an insiders release or a normal release completes, we will also
trigger Tailwind Play, to update its dependencies to the latest version
of Tailwind CSS.
---
Note: some of the GitHub Action workflows still refer to the `next`
branch instead of the `main` branch. If we later today want to get a new
release out, we can merge `next` into `main` and update the workflows
accordingly.
---
This is hard to test, but I started from the existing release.yml file
and adjusted things accordingly. The biggest change is related to the
insiders version. If you look at this temporary
[commit](572dddfc33),
you can see that the publishing (dry-run) seems to work as expected:
<img width="1508" alt="image"
src="https://github.com/user-attachments/assets/c075e788-dcbc-4200-aa32-2b9a3c54d629"
/>
Closes#15220
This PR fixes an issue where the upgrade tool would not be able to load
some JavaScript config files across different drive letters on Windows.
The issue in detail is that `path.relative(…)` tries to build a relative
path but if the file is inside the same folder, it won't start the
relative path with a `./` so we manually appended it in case that it
isn't there. The issue on Windows specifically is that
`file.relative(…)` can also return a legit absolute path, e.g. when the
file is on a different drive. In this case we obviously don't want to
prefix a path with `./`.
## Test plan
To reproduce this issue, I checked out a Tailwind v3 project _on a
different drive letter than my Windows installation_. In that case, I
was adding a repo inside `D:` while `npm` was installed in `C:`. I then
run `npx @tailwindcss/upgrade` to reproduce the issue.
The fix was validated with a local `bun` run of the upgrade tool:

This PR fixes an issue where classes such as `text-sm/none` don't work
as expected. The reason for this is that `leading-none` is the only
hardcoded leading utility and is not coming from the `@theme`. This
means that `text-sm/none` tries to do a lookup for `none` but it won't
resolve.
This PR fixes that by allowing `none` as a modifier.
While working on this, I noticed that `text-sm/none` _did_ generate CSS:
```css
.text-sm\/none {
font-size: var(--text-sm);
}
```
Notice that the `line-height` is missing. This means that any modifier
that can't be resolved doesn't get the `line-height` set, but it _will_
generate CSS. In this case, no CSS should have been generated.
Otherwise, all of these generate CSS which will only bloat your CSS and
won't
work as expected. E.g.: `text-sm/foo`, `text-sm/bar`, and `text-sm/baz`:
```css
.text-sm\/bar {
font-size: var(--text-sm);
}
.text-sm\/baz {
font-size: var(--text-sm);
}
.text-sm\/foo {
font-size: var(--text-sm);
}
```
Fixes: #15911
Update the `open` variant to addtionally match the new `:open` pseudo
class.
See spec at https://drafts.csswg.org/selectors-4/#open-state
See Chromium intent to ship:
https://groups.google.com/a/chromium.org/g/blink-dev/c/Pdo4oOXYKcA
`:open` matches open `<details>` and `<dialog>` elements (already
covered by [open]), but also matches select elements with their picker
open and inputs with their picker open.
Thanks to `:is()` taking a forgiving selector list, this is safe to add
even with limited browser support.
Co-authored-by: Robin Malfait <malfait.robin@gmail.com>
This PR fixes an issue where we didn't always correctly validated
invalid CSS variables when using the CSS variable shorthand syntax.
This PR fixes that by ensuring we start with `--`. We can't validate
that the variable exists at runtime, but we can validate if it looks
like a valid CSS variable.
We can go a step further by validating if the CSS variable is valid
syntax (e.g.: all characters are valid), but we can introduce this if
this is causing actual issues in projects.
```
p-(a-b)
```
Used to compile to:
```css
.p-\(a-b\) {
padding: var(a-b);
}
```
But not anymore.
This PR adds `outline-color` to the transition-property again, and
updates the implementation for `outline-hidden`.
The `outline-hidden` will behave exactly the same as `outline-none`
_except_ in forced colors mode. In forced colors mode, `outline-hidden`
will force a 2px solid border.
Closes: #15591
Variants like this can't be easily negated by our current system:
```css
@custom-variant dark {
&.is-dark {
@slot;
}
@media (prefers-color-scheme: dark) {
@slot;
}
}
```
Right now it produces the following CSS which is logically incorrect:
```css
.utility-name {
&:not(.is-dark) {
/* ... */
}
@media not (prefers-color-scheme: dark) {
/* ... */
}
}
```
The correct CSS is this which requires moving things around:
```css
.utility-name {
@media not (prefers-color-scheme: dark) {
&:not(.is-dark) {
/* ... */
}
}
}
```
We're opting to disable this instead of generating incorrect CSS for
now. I'd like to bring this back in the future for simpler cases in the
future.
This PR replaces `@variant` with `@custom-variant` for registering
custom variants via your CSS.
In addition, this PR introduces `@variant` that can be used in your CSS
to use a variant while writing custom CSS.
E.g.:
```css
.btn {
background: white;
@variant dark {
background: black;
}
}
```
Compiles to:
```css
.btn {
background: white;
}
@media (prefers-color-scheme: dark) {
.btn {
background: black;
}
}
```
For backwards compatibility, the `@variant` rules that don't have a body
and are
defined inline:
```css
@variant hocus (&:hover, &:focus);
```
And `@variant` rules that are defined with a body and a `@slot`:
```css
@variant hocus {
&:hover, &:focus {
@slot;
}
}
```
Will automatically be upgraded to `@custom-variant` internally, so no
breaking changes are introduced with this PR.
---
TODO:
- [x] ~~Decide whether we want to allow multiple variants and if so,
what syntax should be used. If not, nesting `@variant <variant> {}` will
be the way to go.~~ Only a single `@variant <variant>` can be used, if
you want to use multiple, nesting should be used:
```css
.foo {
@variant hover {
@variant focus {
color: red;
}
}
}
```
This PR changes the syntax for the `--alpha(…)` function to look like
more modern CSS.
The arguments to apply an alpha to a color is using the `/` syntax
instead of the comma syntax.
```diff
- --alpha(color, 50%)
+ --alpha(color / 50%)
```
This syntax is now similar to modern `rgb(0 0 0 / 50%)` syntax in CSS.
Closes#15636Closes#15638Closes#15637
I noticed that I forgot to update the bundled `lightningcss`
dependencies in the `standalone` project. This makes sure we have the
same version everywhere.
This PR fixes an issue where functional utilities configured via CSS
don't resolve the values correctly.
We always fully resolved the values as-if a `@theme inline` was used.
We used to compile the following code:
```css
@theme {
--tab-size-github: 8;
}
@utility tab-* {
tab-size: --value(--tab-size);
}
```
Into:
```css
:root {
--tab-size-github: 8;
}
.tab-github {
tab-size: 8;
}
```
But it should be referencing the variable instead:
```css
:root {
--tab-size-github: 8;
}
.tab-github {
tab-size: var(--tab-size-github);
}
```
However, if you used `@theme inline reference`, it should inline the
value:
```css
@theme inline reference {
--tab-size-github: 8;
}
@utility tab-* {
tab-size: --value(--tab-size);
}
```
This will now correctly compile to:
```css
.tab-github {
tab-size: 8;
}
```
This PR fixes an issue if you want to reset a namespace like:
```css
@theme {
--color-*: initial;
}
```
That some formatters such as Biome won't allow this syntax. To solve
that, this PR allows you to use an escaped `*` character.
```css
@theme {
--color-\*: initial;
}
```
Fixes: #15602
This PR improves the upgrade tool to make sure that newly upgraded
`--spacing(2)` CSS functions is pretty printed to prevent unambiguous
looking classes (even though it compiles correctly).
If you have a class such as `m-[calc(100dvh-theme(spacing.2))]`, then we
used to convert it to `m-[calc(100dvh-calc(var(--spacing)*2))]`. But
recently we introduced the `--spacing(2)` CSS function which means that
the output now looks like this instead: `m-[calc(100dvh---spacing(2))]`.
The triple `-` is valid because the first `-` is the minus sign, the
next two `-` characters are from the function.
One solution is to introduce spaces via underscores:
```
m-[calc(100dvh_-_--spacing(2))]
```
But a simpler solution, is to wrap the `--spacing(2)` in parens to
remove the underscores and improve the readability of the `---`
characters.
```
m-[calc(100dvh-(--spacing(2)))]
```
Here is everything you need to know about this upgrade. Please take a
good look at what changed and the test results before merging this pull
request.
### What changed?
#### ✳️ @types/react (18.3.12 → 19.0.2) ·
[Repo](https://github.com/DefinitelyTyped/DefinitelyTyped)
Sorry, we couldn't find anything useful about this release.
---

[Depfu](https://depfu.com) will automatically keep this PR
conflict-free, as long as you don't add any commits to this branch
yourself. You can also trigger a rebase manually by commenting with
`@depfu rebase`.
<details><summary>All Depfu comment commands</summary>
<blockquote><dl>
<dt>@depfu rebase</dt><dd>Rebases against your default branch and
redoes this update</dd>
<dt>@depfu recreate</dt><dd>Recreates this PR, overwriting any edits
that you've made to it</dd>
<dt>@depfu merge</dt><dd>Merges this PR once your tests are passing and
conflicts are resolved</dd>
<dt>@depfu cancel merge</dt><dd>Cancels automatic merging of this
PR</dd>
<dt>@depfu close</dt><dd>Closes this PR and deletes the branch</dd>
<dt>@depfu reopen</dt><dd>Restores the branch and reopens this PR (if
it's closed)</dd>
<dt>@depfu pause</dt><dd>Ignores all future updates for this dependency
and closes this PR</dd>
<dt>@depfu pause [minor|major]</dt><dd>Ignores all future minor/major
updates for this dependency and closes this PR</dd>
<dt>@depfu resume</dt><dd>Future versions of this dependency will
create PRs again (leaves this PR as is)</dd>
</dl></blockquote>
</details>
Co-authored-by: depfu[bot] <23717796+depfu[bot]@users.noreply.github.com>
Here is everything you need to know about this upgrade. Please take a
good look at what changed and the test results before merging this pull
request.
### What changed?
#### ✳️ react (18.3.1 → 19.0.0) ·
[Repo](https://github.com/facebook/react) ·
[Changelog](https://github.com/facebook/react/blob/main/CHANGELOG.md)
<details>
<summary>Release Notes</summary>
<h4><a
href="https://github.com/facebook/react/releases/tag/v19.0.0">19.0.0</a></h4>
<blockquote><em>More info than we can show here.</em></blockquote>
<p><em>Does any of this look wrong? <a
href="https://depfu.com/packages/npm/react/feedback">Please let us
know.</a></em></p>
</details>
<details>
<summary>Commits</summary>
<p><a
href="f1338f8080...7aa5dda3b3">See
the full diff on Github</a>. The new version differs by more commits
than we can show here.</p>
</details>
#### ✳️ react-dom (18.3.1 → 19.0.0) ·
[Repo](https://github.com/facebook/react) ·
[Changelog](https://github.com/facebook/react/blob/main/CHANGELOG.md)
<details>
<summary>Release Notes</summary>
<h4><a
href="https://github.com/facebook/react/releases/tag/v19.0.0">19.0.0</a></h4>
<blockquote><em>More info than we can show here.</em></blockquote>
<p><em>Does any of this look wrong? <a
href="https://depfu.com/packages/npm/react-dom/feedback">Please let us
know.</a></em></p>
</details>
<details>
<summary>Commits</summary>
<p><a
href="f1338f8080...7aa5dda3b3">See
the full diff on Github</a>. The new version differs by more commits
than we can show here.</p>
</details>
---

[Depfu](https://depfu.com) will automatically keep this PR
conflict-free, as long as you don't add any commits to this branch
yourself. You can also trigger a rebase manually by commenting with
`@depfu rebase`.
<details><summary>All Depfu comment commands</summary>
<blockquote><dl>
<dt>@depfu rebase</dt><dd>Rebases against your default branch and
redoes this update</dd>
<dt>@depfu recreate</dt><dd>Recreates this PR, overwriting any edits
that you've made to it</dd>
<dt>@depfu merge</dt><dd>Merges this PR once your tests are passing and
conflicts are resolved</dd>
<dt>@depfu cancel merge</dt><dd>Cancels automatic merging of this
PR</dd>
<dt>@depfu close</dt><dd>Closes this PR and deletes the branch</dd>
<dt>@depfu reopen</dt><dd>Restores the branch and reopens this PR (if
it's closed)</dd>
<dt>@depfu pause</dt><dd>Ignores all future updates for this dependency
and closes this PR</dd>
<dt>@depfu pause [minor|major]</dt><dd>Ignores all future minor/major
updates for this dependency and closes this PR</dd>
<dt>@depfu resume</dt><dd>Future versions of this dependency will
create PRs again (leaves this PR as is)</dd>
</dl></blockquote>
</details>
Co-authored-by: depfu[bot] <23717796+depfu[bot]@users.noreply.github.com>
Here is everything you need to know about this upgrade. Please take a
good look at what changed and the test results before merging this pull
request.
### What changed?
#### ✳️ @types/react-dom (18.3.1 → 19.0.2) ·
[Repo](https://github.com/DefinitelyTyped/DefinitelyTyped)
Sorry, we couldn't find anything useful about this release.
---

[Depfu](https://depfu.com) will automatically keep this PR
conflict-free, as long as you don't add any commits to this branch
yourself. You can also trigger a rebase manually by commenting with
`@depfu rebase`.
<details><summary>All Depfu comment commands</summary>
<blockquote><dl>
<dt>@depfu rebase</dt><dd>Rebases against your default branch and
redoes this update</dd>
<dt>@depfu recreate</dt><dd>Recreates this PR, overwriting any edits
that you've made to it</dd>
<dt>@depfu merge</dt><dd>Merges this PR once your tests are passing and
conflicts are resolved</dd>
<dt>@depfu cancel merge</dt><dd>Cancels automatic merging of this
PR</dd>
<dt>@depfu close</dt><dd>Closes this PR and deletes the branch</dd>
<dt>@depfu reopen</dt><dd>Restores the branch and reopens this PR (if
it's closed)</dd>
<dt>@depfu pause</dt><dd>Ignores all future updates for this dependency
and closes this PR</dd>
<dt>@depfu pause [minor|major]</dt><dd>Ignores all future minor/major
updates for this dependency and closes this PR</dd>
<dt>@depfu resume</dt><dd>Future versions of this dependency will
create PRs again (leaves this PR as is)</dd>
</dl></blockquote>
</details>
Co-authored-by: depfu[bot] <23717796+depfu[bot]@users.noreply.github.com>
Upgrading `lightningcss` to fix invalid `list-style: none` conversion.
I've also reverted the change to preflight while at it, since it's no
longer necessary.
This PR adds a `main` and `browser` field for the `@tailwindcss/browser`
package.
In the package, we do have the `exports` field setup, which is an
alternative to the `main` field according to the docs:
> The "exports" provides a modern alternative to "main" …
>
> —
https://docs.npmjs.com/cli/v10/configuring-npm/package-json?v=true#exports
However, if you look at the unpkg link:
https://unpkg.com/@tailwindcss/browser, it tries to load the `index.js`
file. This is probably a bug in the unpkg resolver.
That said, if you look at other CDNs such as esm.sh, it does resolve
correctly: https://esm.sh/@tailwindcss/browser
According to the npm docs:
> If `main` is not set, it defaults to `index.js` in the package's root
folder.
>
> —
https://docs.npmjs.com/cli/v10/configuring-npm/package-json?v=true#main
This explains why unpkg is trying to load the `index.js` file.
Additionally, the npm docs also mention the `browser` field:
> If your module is meant to be used client-side the browser field
should be used instead of the main field. This is helpful to hint users
that it might rely on primitives that aren't available in Node.js
modules. (e.g. window)
>
> —
https://docs.npmjs.com/cli/v10/configuring-npm/package-json?v=true#browser
So this PR also adds that field just to be sure.
Here is everything you need to know about this update. Please take a
good look at what changed and the test results before merging this pull
request.
### What changed?
#### ✳️ prettier (3.3.3 → 3.4.2) ·
[Repo](https://github.com/prettier/prettier) ·
[Changelog](https://github.com/prettier/prettier/blob/main/CHANGELOG.md)
<details>
<summary>Release Notes</summary>
<h4><a
href="https://github.com/prettier/prettier/releases/tag/3.4.2">3.4.2</a></h4>
<blockquote><p dir="auto">🔗 <a
href="https://bounce.depfu.com/github.com/prettier/prettier/blob/main/CHANGELOG.md#342">Changelog</a></p></blockquote>
<h4><a
href="https://github.com/prettier/prettier/releases/tag/3.4.1">3.4.1</a></h4>
<blockquote><p dir="auto">🔗 <a
href="https://bounce.depfu.com/github.com/prettier/prettier/blob/main/CHANGELOG.md#341">Changelog</a></p></blockquote>
<p><em>Does any of this look wrong? <a
href="https://depfu.com/packages/npm/prettier/feedback">Please let us
know.</a></em></p>
</details>
<details>
<summary>Commits</summary>
<p><a
href="52829385bc...cca946176c">See
the full diff on Github</a>. The new version differs by more commits
than we can show here.</p>
</details>
---

[Depfu](https://depfu.com) will automatically keep this PR
conflict-free, as long as you don't add any commits to this branch
yourself. You can also trigger a rebase manually by commenting with
`@depfu rebase`.
<details><summary>All Depfu comment commands</summary>
<blockquote><dl>
<dt>@depfu rebase</dt><dd>Rebases against your default branch and
redoes this update</dd>
<dt>@depfu recreate</dt><dd>Recreates this PR, overwriting any edits
that you've made to it</dd>
<dt>@depfu merge</dt><dd>Merges this PR once your tests are passing and
conflicts are resolved</dd>
<dt>@depfu cancel merge</dt><dd>Cancels automatic merging of this
PR</dd>
<dt>@depfu close</dt><dd>Closes this PR and deletes the branch</dd>
<dt>@depfu reopen</dt><dd>Restores the branch and reopens this PR (if
it's closed)</dd>
<dt>@depfu pause</dt><dd>Ignores all future updates for this dependency
and closes this PR</dd>
<dt>@depfu pause [minor|major]</dt><dd>Ignores all future minor/major
updates for this dependency and closes this PR</dd>
<dt>@depfu resume</dt><dd>Future versions of this dependency will
create PRs again (leaves this PR as is)</dd>
</dl></blockquote>
</details>
Co-authored-by: depfu[bot] <23717796+depfu[bot]@users.noreply.github.com>
Here is everything you need to know about this update. Please take a
good look at what changed and the test results before merging this pull
request.
### What changed?
#### ✳️ enhanced-resolve (5.17.1 → 5.18.0) ·
[Repo](https://github.com/webpack/enhanced-resolve)
<details>
<summary>Release Notes</summary>
<h4><a
href="https://github.com/webpack/enhanced-resolve/releases/tag/v5.18.0">5.18.0</a></h4>
<blockquote><h3 dir="auto">Features</h3>
<ul dir="auto">
<li>Added wildcards support for aliases</li>
</ul></blockquote>
<p><em>Does any of this look wrong? <a
href="https://depfu.com/packages/npm/enhanced-resolve/feedback">Please
let us know.</a></em></p>
</details>
<details>
<summary>Commits</summary>
<p><a
href="247edebc90...27e457a905">See
the full diff on Github</a>. The new version differs by 9 commits:</p>
<ul>
<li><a
href="27e457a905"><code>chore(release):
5.18.0</code></a></li>
<li><a
href="88ceebe3cc"><code>feat:
add wildcards support for aliases</code></a></li>
<li><a
href="35b67ce834"><code>feat:
add wildcards</code></a></li>
<li><a
href="4fbcfa1c83"><code>chore(deps):
bump cross-spawn from 7.0.3 to 7.0.6</code></a></li>
<li><a
href="572a54f0c6"><code>chore(deps):
bump cross-spawn from 7.0.3 to 7.0.6</code></a></li>
<li><a
href="af4e2fb155"><code>ci:
add Node.js v23</code></a></li>
<li><a
href="bf443c04ac"><code>ci:
add Node.js v23</code></a></li>
<li><a
href="72999caf00"><code>chore(deps):
bump micromatch from 4.0.5 to 4.0.8</code></a></li>
<li><a
href="fbee162cc2"><code>chore(deps):
bump micromatch from 4.0.5 to 4.0.8</code></a></li>
</ul>
</details>
---

[Depfu](https://depfu.com) will automatically keep this PR
conflict-free, as long as you don't add any commits to this branch
yourself. You can also trigger a rebase manually by commenting with
`@depfu rebase`.
<details><summary>All Depfu comment commands</summary>
<blockquote><dl>
<dt>@depfu rebase</dt><dd>Rebases against your default branch and
redoes this update</dd>
<dt>@depfu recreate</dt><dd>Recreates this PR, overwriting any edits
that you've made to it</dd>
<dt>@depfu merge</dt><dd>Merges this PR once your tests are passing and
conflicts are resolved</dd>
<dt>@depfu cancel merge</dt><dd>Cancels automatic merging of this
PR</dd>
<dt>@depfu close</dt><dd>Closes this PR and deletes the branch</dd>
<dt>@depfu reopen</dt><dd>Restores the branch and reopens this PR (if
it's closed)</dd>
<dt>@depfu pause</dt><dd>Ignores all future updates for this dependency
and closes this PR</dd>
<dt>@depfu pause [minor|major]</dt><dd>Ignores all future minor/major
updates for this dependency and closes this PR</dd>
<dt>@depfu resume</dt><dd>Future versions of this dependency will
create PRs again (leaves this PR as is)</dd>
</dl></blockquote>
</details>
Co-authored-by: depfu[bot] <23717796+depfu[bot]@users.noreply.github.com>
This PR makes sure that the `--theme(…)` CSS function can only be used
with the modern syntax. For backwards compatibility, the `theme(…)`
function must be used with the older dot notation.
This PR improves the codemod tool to simplify 2 things:
1. Whenever you have a `theme(…)` call, we try to change it to a
`var(…)`, but if that doesn't work for some reason, we will make sure to
at least convert it to the more modern `--theme(…)`.
2. When converting `theme(spacing.2)`, we used to convert it to
`calc(var(--spacing)*2)`, but now we will convert it to `--spacing(2)`
instead.
Closes#15438Closes#15560Closes#15561Closes#15562
This PR upgrades `lightningcss` to `1.29.0` and uses the [new feature
flag](304389600f)
to disable the light-dark function transpilation.
This PR fixes an issue where JavaScript plugins were still able to
contribute `@keyframes` when loaded inside an `@reference` import. This
was possible because we only gated the `addBase` API and not the
`addUtilities` one which also has a special branch to handle `@keyframe`
rules.
To make this work, we have to create a new instance of the plugin API
that has awareness of wether the plugin accessing it is inside reference
import mode.
## Test plan
Added a unit test that reproduces the issue observed via #15544
This PR fixes an issue where static utilities defined via `@utility`
wasn't possible if the name starts with `-`.
There are plenty of static utilities that start with `-`, but it wasn't
possible to register them via the `@utility` directive, only via the JS
API.
Example of a core utility that is now valid:
```css
@utility -inset-full {
inset: -100%;
}
```
This PR implements new CSS functions that you can use in your CSS (or
even in arbitrary value position).
For starters, we renamed the `theme(…)` function to `--theme(…)`. The
legacy `theme(…)` function is still available for backwards
compatibility reasons, but this allows us to be future proof since
`--foo(…)` is the syntax the CSS spec recommends. See:
https://drafts.csswg.org/css-mixins/
In addition, this PR implements a new `--spacing(…)` function, this
allows you to write:
```css
@import "tailwindcss";
@theme {
--spacing: 0.25rem;
}
.foo {
margin: --spacing(4):
}
```
This is syntax sugar over:
```css
@import "tailwindcss";
@theme {
--spacing: 0.25rem;
}
.foo {
margin: calc(var(--spacing) * 4);
}
```
If your `@theme` uses the `inline` keyword, we will also make sure to
inline the value:
```css
@import "tailwindcss";
@theme inline {
--spacing: 0.25rem;
}
.foo {
margin: --spacing(4):
}
```
Boils down to:
```css
@import "tailwindcss";
@theme {
--spacing: 0.25rem;
}
.foo {
margin: calc(0.25rem * 4); /* And will be optimised to just 1rem */
}
```
---
Another new function function we added is the `--alpha(…)` function that
requires a value, and a number / percentage value. This allows you to
apply an alpha value to any color, but with a much shorter syntax:
```css
@import "tailwindcss";
.foo {
color: --alpha(var(--color-red-500), 0.5);
}
```
This is syntax sugar over:
```css
@import "tailwindcss";
.foo {
color: color-mix(in oklab, var(--color-red-500) 50%, transparent);
}
```
---------
Co-authored-by: Philipp Spiess <hello@philippspiess.com>
Co-authored-by: Jordan Pittman <jordan@cryptica.me>
Co-authored-by: Jonathan Reinink <jonathan@reinink.ca>