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 diff --git a/packages/tailwindcss/src/utils/decode-arbitrary-value.test.ts b/packages/tailwindcss/src/utils/decode-arbitrary-value.test.ts index 19025d5b4bfa..0bc4d425cdd2 100644 --- a/packages/tailwindcss/src/utils/decode-arbitrary-value.test.ts +++ b/packages/tailwindcss/src/utils/decode-arbitrary-value.test.ts @@ -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))'], [ diff --git a/packages/tailwindcss/src/utils/math-operators.ts b/packages/tailwindcss/src/utils/math-operators.ts index 523fcce208cf..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 @@ -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 }