Fix missing space around - when using % regression (#18289)

This PR fixes a regression we shipped in v4.1.9, when using arbitrary
values and injecting spaces around operator.

When you use `w-[calc(100%-var(--foo))]`, you expect that this generates
valid CSS:

```css
width: calc(100% - var(--foo));
```

But due to a regression, we generated:

```css
width: calc(100%-var(--foo));
```

Which is invalid CSS.

This is because the algorithm we used to know when we had to inject a
space around the `-` didn't take the `%` sign into account.

We also didn't handle uppercase units like `123PX` properly. This PR
fixes both issues.

## Test plan

1. Added a regression test for the `%`
2. Added a regression test for uppercase units like `123PX`

Fixes: #18288
This commit is contained in:
Robin Malfait 2025-06-11 22:18:14 +02:00 • committed by GitHub
parent 427649eee4
commit ddb0beff66
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 18 additions and 2 deletions

View file

@ -7,7 +7,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased]
- Nothing yet!
### Fixed
- Fix missing space around `-` when using `%` ([#18289](https://github.com/tailwindlabs/tailwindcss/pull/18289))
## [4.1.9] - 2025-06-11

View file

@ -84,6 +84,12 @@ describe('adds spaces around math operators', () => {
['calc(theme(spacing.foo-2))', 'calc(theme(spacing.foo-2))'],
['calc(theme(spacing.foo-bar))', 'calc(theme(spacing.foo-bar))'],
// With percentages
['calc(100%-var(--foo))', 'calc(100% - var(--foo))'],
// With uppercase units
['calc(100PX-theme(spacing.1))', 'calc(100PX - theme(spacing.1))'],
// Preserving CSS keyword tokens like fit-content without splitting around hyphens in complex expressions
['min(fit-content,calc(100dvh-4rem))', 'min(fit-content, calc(100dvh - 4rem))'],
[

View file

@ -1,5 +1,7 @@
const LOWER_A = 0x61
const LOWER_Z = 0x7a
const UPPER_A = 0x41
const UPPER_Z = 0x5a
const LOWER_E = 0x65
const UPPER_E = 0x45
const ZERO = 0x30
@ -12,6 +14,7 @@ const OPEN_PAREN = 0x28
const CLOSE_PAREN = 0x29
const COMMA = 0x2c
const SPACE = 0x20
const PERCENT = 0x25
const MATH_FUNCTIONS = [
'calc',
@ -62,7 +65,12 @@ export function addWhitespaceAroundMathOperators(input: string) {
// If we saw a number before, and we see normal a-z character, then we
// assume this is a value such as `123px`
else if (valuePos !== null && char >= LOWER_A && char <= LOWER_Z) {
else if (
valuePos !== null &&
(char === PERCENT ||
(char >= LOWER_A && char <= LOWER_Z) ||
(char >= UPPER_A && char <= UPPER_Z))
) {
valuePos = i
}