diff --git a/CHANGELOG.md b/CHANGELOG.md index ba736074e..64c0ea940 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,6 +22,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Prevent `@tailwindcss/vite` from crashing on every edit under Vite's experimental `bundledDev` mode ([#20379](https://github.com/tailwindlabs/tailwindcss/pull/20379)) - Ensure `@tailwindcss/oxide` falls back to WASM on platforms without native bindings ([#20383](https://github.com/tailwindlabs/tailwindcss/pull/20383)) - Detect classes in Ruby percent literals using angle brackets or custom delimiters (e.g. `%w`, `%w|flex|`), including in Slim and Haml templates ([#20387](https://github.com/tailwindlabs/tailwindcss/pull/20387)) +- Preserve whitespace in `--default(…)` values in custom functional utilities (e.g. `--default(box alphabetic)` no longer becomes `boxalphabetic`) ([#20392](https://github.com/tailwindlabs/tailwindcss/pull/20392)) ## [4.3.3] - 2026-07-16 diff --git a/packages/tailwindcss/src/utilities.test.ts b/packages/tailwindcss/src/utilities.test.ts index 9b514cda7..c9d4a5ff0 100644 --- a/packages/tailwindcss/src/utilities.test.ts +++ b/packages/tailwindcss/src/utilities.test.ts @@ -31000,6 +31000,34 @@ describe('custom utilities', () => { expect(await run(['example-123/foo'], input)).toEqual('') }) + test('the value of `--default(…)` is emitted as-is', async () => { + let input = css` + @theme reference { + --text-box-trim-trim-both: trim-both; + --text-box-edge-cap: cap alphabetic; + } + + @utility trim-* { + text-box: --value(--text-box-trim-*) + --modifier(--text-box-edge-*, --default(box alphabetic)); + } + + @tailwind utilities; + ` + + expect(await run(['trim-trim-both', 'trim-trim-both/cap'], input)).toMatchInlineSnapshot(` + " + .trim-trim-both { + text-box: var(--text-box-trim-trim-both, trim-both) box alphabetic; + } + + .trim-trim-both\\/cap { + text-box: var(--text-box-trim-trim-both, trim-both) var(--text-box-edge-cap, cap alphabetic); + } + " + `) + }) + test('modifiers', async () => { let input = css` @theme reference { diff --git a/packages/tailwindcss/src/utilities.ts b/packages/tailwindcss/src/utilities.ts index 54b472c60..6c4a20cbc 100644 --- a/packages/tailwindcss/src/utilities.ts +++ b/packages/tailwindcss/src/utilities.ts @@ -6193,6 +6193,15 @@ export function createCssUtility(node: AtRule) { let args = segment(ValueParser.toCss(fn.nodes), ',') for (let [idx, arg] of args.entries()) { + arg = arg.trim() + + // The value of `--default(…)` is emitted as-is, so it should not be + // normalized. + if (arg.startsWith('--default(')) { + args[idx] = arg + continue + } + // Transform escaped `\\*` -> `*` arg = arg.replace(/\\\*/g, '*')