No description
Find a file
Robin Malfait df6209ab8b
Canonicalize negative arbitrary values (#19858)
This PR adds a few more canonicalizations for some cases I noticed on
our templates.

When dealing with arbitrary values, and the utility is a "negative"
utility, then we will try to put the `-` inside of the arbitrary value:

```diff
- -left-[9rem]
+ left-[-9rem]
```

The idea is that the arbitrary value is already an escape hatch for when
a value is not available by default. The `-` in front uses an implicit
`calc(<expression> * -1)` which might be confusion if you have an value
like this already.

This also can allow for some further optimizations. For example
```diff
- -mt-[492px]
  ↓↓↓↓↓↓↓                           Into a simpler arbitrary value
+ mt-[-492px]
  ↓↓↓↓↓↓↓                           Into a bare value
+ mt-123
```

This PR also improve the constant folding of calc expressions a bit more
such that nested calc expressions with 2 constants and an unknown can be
folded. Bit of a mouthful, but it allows us to handle this:
```diff
- mt-[calc(-1*calc(-1*var(--foo)))]
  ↓↓↓↓↓↓↓                           The -1 * -1 becomes a no-op
+ mt-[var(--foo)]
  ↓↓↓↓↓↓↓                           Into the shorthand for CSS variables
+ mt-(--foo)
```

Now that we can handle moving the `-` into the arbitrary value, there
are also cases where we can get the `-` _out_ of the arbitrary value:
```diff
- mt-[calc(-1*var(--foo))]
  ↓↓↓↓↓↓↓                           Simplify calc, move `-` to the front
+ -mt-[var(--foo)]
  ↓↓↓↓↓↓↓                           Into the shorthand for CSS variables
+ -mt-(--foo)
```

Another missing piece that this PR adds is the concept of canonicalizing
or normalizing calc expressions. This is a separate step used when
calculating the signature for each utility. This allows us to normalize
`calc(-1*var(--foo))` and `calc(var(--foo)*-1)`. Without this they would
not be considered the same, but not it will.

It's only used when comparing values, it won't unify the actual
arbitrary values with this logic (at least for now).

With the additional constant folding logic and the canonicalization when
comparing signatures it unlocks the necessary power to perform the above
transformations.

## Test plan

1. Existing tests still pass
2. Added additional tests for the constant folding logic
3. Added tests for the canonicalization of calc expressions
4. Added new tests where we move the `-` inside the value, or move the
`-` outside of the arbitrary value.
2026-03-26 14:44:09 +01:00
.github chore: Update outdated GitHub Actions versions (#19577) 2026-02-18 12:27:13 +00:00
crates Make upgrade tooling more stable (#19846) 2026-03-24 17:24:12 +01:00
integrations Make upgrade tooling more stable (#19846) 2026-03-24 17:24:12 +01:00
packages Canonicalize negative arbitrary values (#19858) 2026-03-26 14:44:09 +01:00
patches Bump Lightning CSS (#19771) 2026-03-18 15:57:52 +01:00
playgrounds Update bun 1.3.7 → 1.3.9 (patch) (#19678) 2026-02-18 12:00:11 +01:00
scripts Make TypeScript a bit more happy (#19124) 2025-10-14 19:52:46 +00:00
.gitignore Fix slow unit test (#17465) 2025-03-31 15:26:01 +02:00
.prettierignore Bump dependencies (#19608) 2026-02-04 12:38:50 +01:00
Cargo.lock Remove unused crossbeam dependency in oxide (#19256) 2025-11-04 10:37:21 -05:00
Cargo.toml Hoist oxide/crates to just crates (#13333) 2024-03-23 09:00:48 -04:00
CHANGELOG.md Canonicalize negative arbitrary values (#19858) 2026-03-26 14:44:09 +01:00
LICENSE Add README, LICENSE, and CONTRIBUTING (#13088) 2024-03-05 14:45:39 -05:00
package.json Bump Lightning CSS (#19771) 2026-03-18 15:57:52 +01:00
pnpm-lock.yaml Bump Lightning CSS (#19771) 2026-03-18 15:57:52 +01:00
pnpm-workspace.yaml Bump Lightning CSS (#19771) 2026-03-18 15:57:52 +01:00
README.md docs: fix GitHub links to tailwindlabs org (#19686) 2026-02-17 13:06:49 +01:00
rust-toolchain.toml Improve Oxide candidate extractor [0] (#16306) 2025-03-05 11:55:24 +01:00
turbo.json Fix segmentation fault when loading @tailwindcss/oxide in a Worker thread (#17276) 2025-03-18 16:28:20 -04:00
vitest.config.ts Bump Vitest to v4 (#19216) 2025-11-20 18:16:20 -05:00

Tailwind CSS

A utility-first CSS framework for rapidly building custom user interfaces.

Build Status Total Downloads Latest Release License


Documentation

For full documentation, visit tailwindcss.com.

Community

For help, discussion about best practices, or feature ideas:

Discuss Tailwind CSS on GitHub

Contributing

If you're interested in contributing to Tailwind CSS, please read our contributing docs before submitting a pull request.