Skip to content

fix: compile #current to the keyword again - #273

Merged
tenphi merged 1 commit into
mainfrom
fix/current-color-keyword
Aug 24, 2026
Merged

fix: compile #current to the keyword again#273
tenphi merged 1 commit into
mainfrom
fix/current-color-keyword

Conversation

@tenphi

@tenphi tenphi commented Aug 24, 2026

Copy link
Copy Markdown
Owner

#current compiles to currentcolor again, as it did before 3.3.0.

What 3.3.0 changed and why it has to come back

#271 made #current emit var(--current-color) so that a token defined as #current could be faded on Safari 16.4 rather than 18 — relative colour syntax takes a concrete origin from 16.4, while oklch(from currentcolor …) needs 18.

That traded away the property #current exists for. The keyword resolves against the element that reads it, so a #current under an ancestor that faded its own colour reads the faded colour. A ramp built on #current depends on it: the disabled state is expressed once, in color, and everything painted from #current below fades with it.

A variable cannot do that. A faded colour is deliberately never published into --current-color — resolving a color-mix() over currentcolor a second time one level down would fade it twice — so a reader saw through to the unfaded colour above it. Chromatic on cube-ui-kit measured the result on a disabled current.primary chip:

backgroundColor on the disabled chip
3.2.0 oklab(0.571 0.0173617 -0.0955352 / 0.4)
3.3.0 oklch(0.571 0.0971 280.3) — full strength
this PR oklab(0.571 0.0173617 -0.0955352 / 0.4)

What stays

The variable keeps both improvements #271 brought it, with a narrower job — it carries the inherited colour for consumers that need a colour rather than the keyword (hand-authored CSS, anywhere currentcolor will not do), read as $current-color:

  • every colour publishes it, not only a named token, so a reader takes the nearest color rather than the nearest token colour;
  • it is registered with initial-value: currentcolor rather than transparent, so an unpublished reader still resolves against its own element;
  • a value that already reads the inherited colour is not published into it.

What goes back to needing Safari 18

The case #271 set out to fix: a token defined as #current and then faded — { '#ink': '#current', fill: '#ink.5' } — gives relative colour syntax a currentcolor origin. Works in Chrome and Firefox, Safari 18+. The portable alternative is now documented — put the fade in the token itself, { '#ink': '#current.5' }, and it composes through color-mix() on the Safari 16.2 floor.

Tests

The #current block in applied-styles.test.tsx is rewritten against real computed styles, since every step here is a computed-value-time rule that CSS text cannot show:

  • a bare #current under an ancestor at #current.4 lands at / 0.4 — the regression above;
  • a #current.18 nested under a #current.4 still lands at / 0.072;
  • $current-color takes the nearest colour, literal or token, and stands in for the keyword where nothing published it;
  • a value that reads the inherited colour is not republished;
  • the Safari-18 token-fade case is pinned as it behaves in Chromium, with the caveat in the comment.

pnpm test 2079 passing, typecheck, lint and prettier clean.

🤖 Generated with Claude Code

3.3.0 made `#current` emit `var(--current-color)` so a token defined as
`#current` could be faded on Safari 16.4 rather than 18: relative colour syntax
takes a concrete origin from 16.4, while `oklch(from currentcolor …)` needs 18.
That traded away the property `#current` exists for.

The keyword resolves against the element that reads it, so a `#current` under an
ancestor that faded its own colour reads the *faded* colour. A ramp built on
`#current` depends on it — the disabled state is expressed once, in `color`, and
everything painted from `#current` below fades with it. The variable cannot do
that: a faded colour is deliberately never published into `--current-color`,
because resolving it a second time one level down would fade it twice. So a
reader saw through to the unfaded colour above and rendered at full strength.
Chromatic on cube-ui-kit measured it — a disabled chip at `oklab(… / 0.4)` in
3.2.0 came out `oklch(0.571 0.0971 280.3)`, full strength, in 3.3.0.

The variable stays, and keeps both improvements 3.3.0 brought it: every colour
publishes it rather than only a named token, and it is registered with
`initial-value: currentcolor` rather than `transparent`. Its job is narrower now
— it carries the inherited colour for consumers that need a colour rather than
the keyword, read as `$current-color` — and `#current` no longer goes through it.

What 3.3.0 set out to fix goes back to needing Safari 18: a token *defined* as
`#current` and then faded gives relative colour syntax a `currentcolor` origin.
That case is documented with its portable alternative — put the fade in the token
itself, `{ '#ink': '#current.5' }`, and it composes through `color-mix()` on the
Safari 16.2 floor. The two `#current` paths that matter are pinned by
computed-style tests in a real engine: a bare `#current` under a faded ancestor
lands at `.4`, and a `#current.18` nested under a `#current.4` at `.072`.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown
Contributor

📦 Snapshot release

Published 0.0.0-snapshot.c89a8ed.

pnpm add @tenphi/tasty@0.0.0-snapshot.c89a8ed

@tenphi
tenphi merged commit 5cea972 into main Aug 24, 2026
6 of 7 checks passed
@github-actions github-actions Bot mentioned this pull request Aug 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant