* css-icons: restore the caret opacity at rest - #242
Merged
Conversation
`aaf34e96dd` (2024-03-24, "change caret shape from angle to chevron") rewrote the
shared caret rule and, along with the triangle geometry, dropped
`opacity: var(--caret-opacity, .5)` from it. The commit message describes a shape
change only. Since then every caret in the product has rendered fully opaque — 71
of them across `picker`, `dropdown`, `nav`, `menu` and `tree` — where the design
had them at `.5`, reading as a secondary element next to their label.
Restore the declaration on the shared five-variant rule. `--caret-opacity` now
means the at-rest opacity rather than a disabled-only value, so the `:root`
comment is updated to match.
Extend the `.disabled` / `.readonly` rule to the four directional variants. It
covered bare `.caret` only, which was correct while the shared rule carried the
default for all five, but became a coverage gap the moment that default was
deleted: measured before this change, a caret inside `.disabled` resolved to
`.5` while a `.caret-down` beside it resolved to `.7`.
That rule is not redundant with the restored default. `@zui/utilities` applies
`.disabled * {opacity: var(--opacity-disabled)}` at the same specificity as the
base caret rule, so without pinning, a caret inside a disabled container would
resolve to `.7` — brighter than the `.5` it shows when enabled.
Measured after, on every variant and in every state: `.5` at rest, `.5` pinned
inside `.disabled` and `.readonly`, and an ancestor override reaching bare and
directional carets alike.
The docs described `--caret-opacity` as the opacity of a caret inside a `disabled` or `readonly` element, which was accurate for the code as it stood but described a leftover rather than a design. Now that the variable is the at-rest opacity, rewrite the section around what it actually controls. - The example demonstrates the override that consumers will reach for — setting `--caret-opacity` on an ancestor — instead of three carets that only differed by state. - `disabled` and `readonly` are described as pinning the opacity rather than dimming it, with the reason: `.disabled *` would otherwise make a caret in a disabled container brighter than one outside it. - Dropped the pointer to `@zui/tree` setting `.3` on `.tree-toggle`. That declaration is dead — nothing has read it since the 2024 caret reshape — and is removed separately in the branch that clears out tree's orphaned caret variables, so the docs should not present it as a worked example.
Lwrless
force-pushed
the
dev_optimize_caret_opacity
branch
from
August 22, 2026 05:21
cc5acad to
1784aab
Compare
catouse
marked this pull request as ready for review
August 31, 2026 02:47
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Three defects, all left behind by one commit.
aaf34e96dd(2024-03-24, "css-icons: change caret shape from angle to chevron") rewrote the shared caret rule. Before it:The reshape kept the geometry and dropped both
var()reads. The commit message describes a shape change and nothing else.@zui/treeset--caret-opacity: .3on.tree-toggle(13ee4449eb, 2023-06-30, "change toggle icon opacity"). Live and visible when written; dead since the reshape.opacity: 1, where the default had been.5..disabled .caret/.readonly .caretsilently lost coverage of the four directional variants. It targeted bare.caretonly, which was correct while the shared rule carried the default for all five.This PR fixes F-2 and F-3, in
@zui/css-iconsonly. F-1 — tree's dead override — is removed in #241, which touches no file this PR touches.Restores
opacity: var(--caret-opacity)on the shared five-variant rule, so--caret-opacitynow means the at-rest opacity, and extends the.disabled/.readonlyrule to all five variants.Why tree's
.3is not revived (implemented in #241): it was tuned in 2023 for the old caret — a filled 4px triangle. The chevron that replaced it is a 1px stroke, and the same number reads far lighter on it. Rendered side by side in both themes,.3on the chevron is faint enough to read as disabled rather than secondary, which is the wrong signal for a tree expander. Tree toggles should use the.5default like every other caret.Why the
.disabledrule is not redundant with the restored default:@zui/utilitiesapplies.disabled * {opacity: var(--opacity-disabled)}at the same specificity as the base caret rule. Without pinning, a caret inside a disabled container would resolve to.7— brighter than the.5it shows when enabled.Measurements
Before, injecting all five variants into a wrapper:
.caret.disabled.readonlyAfter — every variant identical in every state:
.disabled.readonly--caret-opacity: .9Re-tallied across the consumer dev pages, matching batch 4's census exactly — 71 carets, zero console errors:
pickerdropdownnavmenutreeTree reads
0.3on this branch alone because its--caret-opacity: .3survives until #241 lands; with both merged, all 71 sit at0.5. Merging #241 first avoids that transient, though nothing breaks in the other order.Docs page demo verified on the built site:
0.5default,1and0.3via ancestor override, disabled pinned at0.5inside a0.7container.Rendering impact
This is a deliberate visual change: every caret in the product goes from fully opaque to
.5. That is the point of the PR — restoring a design the 2024 reshape dropped by accident — but it is the one item in this follow-up wave that is not rendering-neutral, and it deserves a look rather than a rubber stamp.Validation
pnpm lint,pnpm typecheck,pnpm check(9 test files / 60 tests, 4 skills tests),pnpm build -- --lib=css-icons --noMinify,pnpm docs:prepare -- --copyandpnpm docs:buildall green.CI on this repo is currently failing for every PR with "The job was not started because your account is locked due to a billing issue" — unrelated to this change.