From fe60c993002e476a41e0f2517f55d414a760645b Mon Sep 17 00:00:00 2001 From: Robin Malfait Date: Wed, 11 Jun 2025 22:03:46 +0200 Subject: [PATCH 1/5] add failing test --- packages/tailwindcss/src/utils/decode-arbitrary-value.test.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/tailwindcss/src/utils/decode-arbitrary-value.test.ts b/packages/tailwindcss/src/utils/decode-arbitrary-value.test.ts index 19025d5b4bfa..dd2f7ed0881a 100644 --- a/packages/tailwindcss/src/utils/decode-arbitrary-value.test.ts +++ b/packages/tailwindcss/src/utils/decode-arbitrary-value.test.ts @@ -84,6 +84,9 @@ 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))'], + // 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))'], [ From 8f4dcb18057555efbac115f9262440c637d9f836 Mon Sep 17 00:00:00 2001 From: Robin Malfait Date: Wed, 11 Jun 2025 22:03:55 +0200 Subject: [PATCH 2/5] take `%` into account --- packages/tailwindcss/src/utils/math-operators.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/tailwindcss/src/utils/math-operators.ts b/packages/tailwindcss/src/utils/math-operators.ts index 523fcce208cf..893e17f7bb93 100644 --- a/packages/tailwindcss/src/utils/math-operators.ts +++ b/packages/tailwindcss/src/utils/math-operators.ts @@ -12,6 +12,7 @@ const OPEN_PAREN = 0x28 const CLOSE_PAREN = 0x29 const COMMA = 0x2c const SPACE = 0x20 +const PERCENT = 0x25 const MATH_FUNCTIONS = [ 'calc', @@ -62,7 +63,7 @@ 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 >= LOWER_A && char <= LOWER_Z) || char === PERCENT)) { valuePos = i } From eb0ec1201836701784936b81b88d16b2e6c572b5 Mon Sep 17 00:00:00 2001 From: Robin Malfait Date: Wed, 11 Jun 2025 22:10:52 +0200 Subject: [PATCH 3/5] add failing test --- packages/tailwindcss/src/utils/decode-arbitrary-value.test.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/tailwindcss/src/utils/decode-arbitrary-value.test.ts b/packages/tailwindcss/src/utils/decode-arbitrary-value.test.ts index dd2f7ed0881a..0bc4d425cdd2 100644 --- a/packages/tailwindcss/src/utils/decode-arbitrary-value.test.ts +++ b/packages/tailwindcss/src/utils/decode-arbitrary-value.test.ts @@ -87,6 +87,9 @@ describe('adds spaces around math operators', () => { // 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))'], [ From d481d5ba9025f42e4d3cba0fe5a40711eb1f78fd Mon Sep 17 00:00:00 2001 From: Robin Malfait Date: Wed, 11 Jun 2025 22:05:21 +0200 Subject: [PATCH 4/5] ensure units can be lower and uppercase --- packages/tailwindcss/src/utils/math-operators.ts | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/packages/tailwindcss/src/utils/math-operators.ts b/packages/tailwindcss/src/utils/math-operators.ts index 893e17f7bb93..d31cc3c526c9 100644 --- a/packages/tailwindcss/src/utils/math-operators.ts +++ b/packages/tailwindcss/src/utils/math-operators.ts @@ -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 @@ -63,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) || char === PERCENT)) { + else if ( + valuePos !== null && + (char === PERCENT || + (char >= LOWER_A && char <= LOWER_Z) || + (char >= UPPER_A && char <= UPPER_Z)) + ) { valuePos = i } From a64a3b204038f4d637213be02935be2d1e4468c1 Mon Sep 17 00:00:00 2001 From: Robin Malfait Date: Wed, 11 Jun 2025 22:13:36 +0200 Subject: [PATCH 5/5] update changelog --- CHANGELOG.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1346213eadb8..e30a1d06d5d9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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