tailwindcss/packages/tailwindcss
한국 2683903b86
Support fractional opacity modifiers for named shadow sizes (#20302)
## Summary

`shadow-*`, `text-shadow-*`, `drop-shadow-*`, and `inset-shadow-*`
accept a bare (non-arbitrary) opacity modifier like `/50`, but the
named-size branch of all four utilities validates it with
`isPositiveInteger(candidate.modifier.value)` instead of
`isValidOpacityValue(candidate.modifier.value)` — the helper every other
opacity/alpha modifier in the codebase uses (`asColor`, used by `bg-*`,
`text-*`, `border-*`, `ring-*`, `fill-*`, `stroke-*`, `decoration-*`,
`accent-*`, `caret-*`, `outline-*`, `placeholder-*`, `divide-*`).

This means a fractional modifier like `/12.5` is silently ignored for a
*named size* (`shadow-sm/12.5` behaves exactly like `shadow-sm`,
dropping the modifier), while the exact same `/12.5` modifier works
correctly on the *color* variant of the same utility
(`shadow-red-500/12.5` → `color-mix(in oklab, var(--color-red-500)
12.5%, transparent)`), since that path already goes through `asColor`.

`drop-shadow-*` is worse: its named-size branch has an extra guard (`if
(candidate.modifier && !alpha) return`) that bails out of the *entire*
utility when a modifier is present but couldn't be resolved to an alpha
— so `drop-shadow-sm/12.5` produces no CSS at all.

This isn't a case of fractional percentages being unsupported by design
— the CHANGELOG entry that introduced `shadow-*/<alpha>` explicitly
describes it as controlling shadow **opacity**, and the color branch of
these same utilities already supports fractional values
(`shadow-red-500/2.25`, `/2.5`, `/2.75` are covered by existing tests).
The named-size branch just never got the same treatment.

**Repro** (verified with `pnpm --filter tailwindcss exec vitest run`):
- `shadow-red-500/12.5` → `color-mix(in oklab, var(--color-red-500)
12.5%, transparent)` (correct)
- `shadow-sm/12.5` → identical output to plain `shadow-sm` (modifier
silently dropped)
- `drop-shadow-sm/12.5` → **no CSS generated at all**
- `shadow-sm/50` (integer, control) → works correctly

## Fix

Replaced `isPositiveInteger(candidate.modifier.value)` with
`isValidOpacityValue(candidate.modifier.value)` in the four affected
utility definitions in `packages/tailwindcss/src/utilities.ts`
(`shadow`, `text-shadow`, `drop-shadow`, `inset-shadow`). No other
changes were needed — once `alpha` resolves correctly, `drop-shadow`'s
existing `if (candidate.modifier && !alpha) return` guard naturally
stops bailing out, since `alpha` is no longer `undefined` for valid
fractional modifiers.

## Test plan

- Added a regression test in
`packages/tailwindcss/src/utilities.test.ts` covering `shadow-sm/12.5`,
`text-shadow-sm/12.5`, `drop-shadow-sm/12.5`, and
`inset-shadow-sm/12.5`.
- Verified via `pnpm --filter tailwindcss exec vitest run` that this
test fails (modifier dropped / empty output) with the fix reverted, and
passes with it applied.
- Ran the full `tailwindcss` package test suite (`pnpm --filter
tailwindcss exec vitest run`) — 4685 tests passing, no regressions.
- Verified formatting on the changed files with `npx prettier --check`.

---------

Co-authored-by: Robin Malfait <malfait.robin@gmail.com>
2026-07-03 12:34:02 +00:00
..
src Support fractional opacity modifiers for named shadow sizes (#20302) 2026-07-03 12:34:02 +00:00
tests Bump dependencies (#19608) 2026-02-04 12:38:50 +01:00
index.css introduce v4 codebase 2024-03-05 14:29:15 +01:00
package.json 4.3.2 (#20281) 2026-06-29 10:10:00 -04:00
playwright.config.ts Bump dependencies (#20095) 2026-05-21 17:58:55 +02:00
preflight.css fix: exclude iframes from focus-visible auto outline in Preflight (#20292) 2026-07-02 10:39:28 +00:00
README.md docs: update package README CI badge to main (#19692) 2026-02-18 11:52:07 +01:00
theme.css Add mauve, olive, mist, and taupe color palettes (#19627) 2026-02-18 11:52:35 +01:00
tsconfig.json Bump dependencies (#19957) 2026-04-24 21:21:12 +02:00
tsup.config.ts Revert: Only expose used CSS variables (#16403) 2025-02-10 13:26:13 +01:00
utilities.css introduce v4 codebase 2024-03-05 14:29:15 +01:00
vitest.config.ts Reduce precision of oklab() arguments in test snapshots (#15210) 2024-11-27 11:06:19 -05:00

Tailwind CSS

A utility-first CSS framework for rapidly building custom user interfaces.

Build Status Total Downloads Latest Release License


Documentation

For full documentation, visit tailwindcss.com.

Community

For help, discussion about best practices, or feature ideas:

Discuss Tailwind CSS on GitHub

Contributing

If you're interested in contributing to Tailwind CSS, please read our contributing docs before submitting a pull request.