diff --git a/packages/tailwindcss/src/utilities.test.ts b/packages/tailwindcss/src/utilities.test.ts index e562cd3be15a..417784dc5628 100644 --- a/packages/tailwindcss/src/utilities.test.ts +++ b/packages/tailwindcss/src/utilities.test.ts @@ -24618,6 +24618,38 @@ test('leading', async () => { `) }) +test('leading-none is not shadowed by --spacing-none', async () => { + expect( + await compileCss( + css` + @theme { + --spacing-none: 0; + } + @tailwind utilities; + `, + ['leading-none'], + ), + ).toMatchInlineSnapshot(` + "@layer properties { + @supports (((-webkit-hyphens: none)) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color: rgb(from red r g b)))) { + *, :before, :after, ::backdrop { + --tw-leading: initial; + } + } + } + + .leading-none { + --tw-leading: 1; + line-height: 1; + } + + @property --tw-leading { + syntax: "*"; + inherits: false + }" + `) +}) + test('tracking', async () => { expect( await compileCss( diff --git a/packages/tailwindcss/src/utilities.ts b/packages/tailwindcss/src/utilities.ts index 62e4510b7309..a7aa965c3d21 100644 --- a/packages/tailwindcss/src/utilities.ts +++ b/packages/tailwindcss/src/utilities.ts @@ -414,10 +414,24 @@ export function createUtilities(theme: Theme) { value = candidate.value.value dataType = candidate.value.dataType } else { - value = theme.resolve( - candidate.value.fraction ?? candidate.value.value, - desc.themeKeys ?? [], - ) + let resolvedValue = candidate.value.fraction ?? candidate.value.value + + // First try resolving against just the primary theme key. + value = theme.resolve(resolvedValue, desc.themeKeys?.slice(0, 1) ?? []) + + // If the primary theme key didn't match, check static values before + // falling back to secondary theme keys (like `--spacing`). This + // ensures e.g. `leading-none` produces `line-height: 1` even when + // `--spacing-none` is defined in the theme. + if (value === null && !negative && desc.staticValues && !candidate.modifier) { + let fallback = desc.staticValues[candidate.value.value] + if (fallback) return fallback.map(cloneAstNode) + } + + // Fall back to the full set of theme keys. + if (value === null) { + value = theme.resolve(resolvedValue, desc.themeKeys ?? []) + } // Automatically handle things like `w-1/2` without requiring `1/2` to // exist as a theme value. @@ -439,11 +453,6 @@ export function createUtilities(theme: Theme) { value = desc.handleBareValue(candidate.value) if (!value?.includes('/') && candidate.modifier) return } - - if (value === null && !negative && desc.staticValues && !candidate.modifier) { - let fallback = desc.staticValues[candidate.value.value] - if (fallback) return fallback.map(cloneAstNode) - } } // If there is no value, don't generate any rules.