Skip to content

fix: dark-mode CSS leaks — listbox hover, base buttons, light badges, grid stripes#5

Merged
andregoepel merged 2 commits into
mainfrom
fix/dark-mode-listbox-hover
Jul 17, 2026
Merged

fix: dark-mode CSS leaks — listbox hover, base buttons, light badges, grid stripes#5
andregoepel merged 2 commits into
mainfrom
fix/dark-mode-listbox-hover

Conversation

@andregoepel

@andregoepel andregoepel commented Jul 17, 2026

Copy link
Copy Markdown
Owner

Two dark-mode fixes in design.css, bundled for one release. Both are the same class of bug: a Radzen style wins over (or is missed by) the design layer, so a light-theme colour leaks onto the dark shell.

1. Listbox item hover unreadable (specificity)

Hovering a RadzenListBox item gave a near-white row with dark, invisible text. design.css styled the hover, but Radzen's material-base uses a deliberate specificity bump — .rz-listbox:not(.rz-state-disabled) .rz-listbox-item:hover:hover (0,5,0) — that beats our .rz-listbox .rz-listbox-item:hover (0,3,0), so the light base-theme colour won.

Fix: match Radzen's selector exactly. Equal specificity → source order decides, and design.css loads after material-base, so our rule wins. Visible on the user/role assignment dialogs.

2. Unmapped tokens leak the light theme (closes #4)

design.css remaps most Radzen tokens but missed a few, leaving Radzen's light defaults:

  • --rz-base / --rz-on-base back ButtonStyle.Base — used by DialogService.Confirm's Cancel button — so every confirm dialog showed one white button.
  • --rz-base-200 backs BadgeStyle.Light; unmapped it paired a light background with the remapped near-white text (~1.2:1 contrast, unreadable).
  • --rz-grid-stripe-* left every second RadzenDataGrid row white.

Fix: map them through the same --ag-* tokens as the rest of the block. Because --ag-* switch per theme, light mode stays correct automatically. Mappings and contrast (11.5:1 dark / 9.5:1 light, both AAA) are from the measurements in #4.

Verification

Both are deterministic CSS fixes (cascade order for #1, token remap for #2), verified by analysis against the real material-base.css (Radzen.Blazor 10.3.2) selector/token chain rather than a screenshot. #2's contrast figures come from the reporter's in-browser measurements against the same stylesheet chain.

Fixes #4.

The listbox-item hover rule lost a specificity contest to Radzen's
material-base, whose selector doubles the pseudo-class and adds a :not()
(`.rz-listbox:not(.rz-state-disabled) .rz-listbox-item:hover:hover`). Our
plain `.rz-listbox-item:hover` is less specific, so in dark mode the light
base-theme hover colour won — dark text on a near-white row, effectively
invisible. Visible anywhere a RadzenListBox is used (e.g. the user/role
assignment dialogs).

Match Radzen's selector exactly; since this layer loads after material-base,
equal specificity resolves in our favour on source order.
…ark mode

design.css remaps most Radzen tokens but missed a few, so the components
using them kept Radzen's light-theme defaults on the dark shell:

- --rz-base / --rz-on-base back ButtonStyle.Base — used by
  DialogService.Confirm's Cancel button — so every confirm dialog showed one
  white button.
- --rz-base-200 backs BadgeStyle.Light; unmapped it paired a light
  background with the remapped near-white text (~1.2:1 contrast, unreadable).
- --rz-grid-stripe-* left every second data-grid row white.

Map them through the same --ag-* tokens as the rest of the block, so light
mode stays correct automatically. Closes #4.
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.

Dark mode: --rz-base, --rz-on-base and the grid stripe tokens are not remapped (light-theme leaks)

1 participant