diff --git a/CHANGELOG.md b/CHANGELOG.md index b4058a7729bf..4b4256ce9377 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Canonicalization: match arbitrary hex colors against theme colors case-insensitively (e.g. `bg-[#fff]` and `bg-[#FFF]` → `bg-white`) ([#20298](https://github.com/tailwindlabs/tailwindcss/pull/20298)) - Prevent Preflight from overriding Firefox's native `iframe:focus-visible` outline styles ([#20292](https://github.com/tailwindlabs/tailwindcss/pull/20292)) - Prevent `theme('colors.foo')` in JS plugins from returning an internal disambiguation object when a CSS theme key shares a prefix with a sibling key like `--color-foo-bar` ([#20299](https://github.com/tailwindlabs/tailwindcss/pull/20299)) +- Ensure fractional opacity modifiers work with named shadow sizes like `shadow-sm/12.5`, `text-shadow-sm/12.5`, `drop-shadow-sm/12.5`, and `inset-shadow-sm/12.5` ([#20302](https://github.com/tailwindlabs/tailwindcss/pull/20302)) ## [4.3.2] - 2026-06-26 diff --git a/packages/tailwindcss/src/utilities.test.ts b/packages/tailwindcss/src/utilities.test.ts index e404a0a90dc2..5201878f2e43 100644 --- a/packages/tailwindcss/src/utilities.test.ts +++ b/packages/tailwindcss/src/utilities.test.ts @@ -24053,6 +24053,7 @@ test('filter', async () => { 'invert-[var(--value)]', 'drop-shadow', 'drop-shadow/25', + 'drop-shadow/12.5', 'drop-shadow-xl', 'drop-shadow-multi', 'drop-shadow-[0_0_red]', @@ -24150,6 +24151,13 @@ test('filter', async () => { filter: var(--tw-blur, ) var(--tw-brightness, ) var(--tw-contrast, ) var(--tw-grayscale, ) var(--tw-hue-rotate, ) var(--tw-invert, ) var(--tw-saturate, ) var(--tw-sepia, ) var(--tw-drop-shadow, ); } + .drop-shadow\\/12\\.5 { + --tw-drop-shadow-alpha: 12.5%; + --tw-drop-shadow-size: drop-shadow(0 1px 1px var(--tw-drop-shadow-color, oklab(0% 0 0 / .125))); + --tw-drop-shadow: drop-shadow(var(--drop-shadow)); + filter: var(--tw-blur, ) var(--tw-brightness, ) var(--tw-contrast, ) var(--tw-grayscale, ) var(--tw-hue-rotate, ) var(--tw-invert, ) var(--tw-saturate, ) var(--tw-sepia, ) var(--tw-drop-shadow, ); + } + .drop-shadow\\/25 { --tw-drop-shadow-alpha: 25%; --tw-drop-shadow-size: drop-shadow(0 1px 1px var(--tw-drop-shadow-color, oklab(0% 0 0 / .25))); @@ -26901,6 +26909,7 @@ test('text-shadow', async () => { 'text-shadow-[shadow:var(--value)]', 'text-shadow-sm/25', + 'text-shadow-sm/12.5', 'text-shadow-[12px_12px_#0088cc]/25', 'text-shadow-[12px_12px_var(--value)]/25', 'text-shadow-[10px_10px]/25', @@ -26979,6 +26988,11 @@ test('text-shadow', async () => { text-shadow: 12px 12px var(--tw-text-shadow-color, oklab(59.9824% -.067 -.124 / .25)); } + .text-shadow-sm\\/12\\.5 { + --tw-text-shadow-alpha: 12.5%; + text-shadow: 0px 1px 2px var(--tw-text-shadow-color, oklab(0% 0 0 / .125)), 0px 2px 2px var(--tw-text-shadow-color, oklab(0% 0 0 / .125)); + } + .text-shadow-sm\\/25 { --tw-text-shadow-alpha: 25%; text-shadow: 0px 1px 2px var(--tw-text-shadow-color, oklab(0% 0 0 / .25)), 0px 2px 2px var(--tw-text-shadow-color, oklab(0% 0 0 / .25)); @@ -27266,6 +27280,7 @@ test('shadow', async () => { 'shadow-[shadow:var(--value)]', 'shadow-sm/25', + 'shadow-sm/12.5', 'shadow-[12px_12px_#0088cc]/25', 'shadow-[12px_12px_var(--value)]/25', 'shadow-[10px_10px]/25', @@ -27368,6 +27383,12 @@ test('shadow', async () => { box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow); } + .shadow-sm\\/12\\.5 { + --tw-shadow-alpha: 12.5%; + --tw-shadow: 0 1px 3px 0 var(--tw-shadow-color, oklab(0% 0 0 / .125)), 0 1px 2px -1px var(--tw-shadow-color, oklab(0% 0 0 / .125)); + box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow); + } + .shadow-sm\\/25 { --tw-shadow-alpha: 25%; --tw-shadow: 0 1px 3px 0 var(--tw-shadow-color, oklab(0% 0 0 / .25)), 0 1px 2px -1px var(--tw-shadow-color, oklab(0% 0 0 / .25)); @@ -27742,6 +27763,7 @@ test('inset-shadow', async () => { 'inset-shadow-[12px_12px_#0088cc,12px_12px_var(--value,#0088cc)]', 'inset-shadow-sm/25', + 'inset-shadow-sm/12.5', 'inset-shadow-[12px_12px_#0088cc]/25', 'inset-shadow-[12px_12px_var(--value)]/25', 'inset-shadow-[10px_10px]/25', @@ -27857,6 +27879,12 @@ test('inset-shadow', async () => { box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow); } + .inset-shadow-sm\\/12\\.5 { + --tw-inset-shadow-alpha: 12.5%; + --tw-inset-shadow: inset 0 1px 1px var(--tw-inset-shadow-color, oklab(0% 0 0 / .125)); + box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow); + } + .inset-shadow-sm\\/25 { --tw-inset-shadow-alpha: 25%; --tw-inset-shadow: inset 0 1px 1px var(--tw-inset-shadow-color, oklab(0% 0 0 / .25)); diff --git a/packages/tailwindcss/src/utilities.ts b/packages/tailwindcss/src/utilities.ts index c9fb0cc439c1..5da9e63e173f 100644 --- a/packages/tailwindcss/src/utilities.ts +++ b/packages/tailwindcss/src/utilities.ts @@ -4618,7 +4618,7 @@ export function createUtilities(theme: Theme) { if (candidate.modifier.kind === 'arbitrary') { alpha = candidate.modifier.value } else { - if (isPositiveInteger(candidate.modifier.value)) { + if (isValidOpacityValue(candidate.modifier.value)) { alpha = `${candidate.modifier.value}%` } } @@ -5427,7 +5427,7 @@ export function createUtilities(theme: Theme) { if (candidate.modifier.kind === 'arbitrary') { alpha = candidate.modifier.value } else { - if (isPositiveInteger(candidate.modifier.value)) { + if (isValidOpacityValue(candidate.modifier.value)) { alpha = `${candidate.modifier.value}%` } } @@ -5573,7 +5573,7 @@ export function createUtilities(theme: Theme) { if (candidate.modifier.kind === 'arbitrary') { alpha = candidate.modifier.value } else { - if (isPositiveInteger(candidate.modifier.value)) { + if (isValidOpacityValue(candidate.modifier.value)) { alpha = `${candidate.modifier.value}%` } } @@ -5699,7 +5699,7 @@ export function createUtilities(theme: Theme) { if (candidate.modifier.kind === 'arbitrary') { alpha = candidate.modifier.value } else { - if (isPositiveInteger(candidate.modifier.value)) { + if (isValidOpacityValue(candidate.modifier.value)) { alpha = `${candidate.modifier.value}%` } }