From 698dfbbd04a345cc64a40a6d44eb3608ff847f20 Mon Sep 17 00:00:00 2001 From: JOY Date: Mon, 26 Oct 2026 01:37:41 +0700 Subject: [PATCH] fix(a11y): mark pressed toggles with the system highlight in forced colors (#1086) Forced colours replace the background and text colours that set a pressed toggle apart, so the selected category on the leaderboard and compare switchers looked like the others in Windows High Contrast. Draw every [aria-pressed="true"] control with Highlight/HighlightText. Co-Authored-By: Claude Opus 5.5 --- apps/web/e2e/selector-state.spec.ts | 24 ++++++++++++++++++++++++ apps/web/src/app/style/scss/_custom.scss | 21 +++++++++++++++++++++ 2 files changed, 45 insertions(+) diff --git a/apps/web/e2e/selector-state.spec.ts b/apps/web/e2e/selector-state.spec.ts index 2e08e9c4..6fceab0a 100644 --- a/apps/web/e2e/selector-state.spec.ts +++ b/apps/web/e2e/selector-state.spec.ts @@ -57,3 +57,27 @@ test('the compare category switcher exposes its state', async ({ page }) => { const group = page.getByRole('group', { name: 'Chọn danh mục đối chiếu' }); await expect(group.getByRole('button', { pressed: true })).toHaveCount(1); }); + +// Forced colours drop the colours that mark the pressed button; it must still +// look different from the others (DOS/Rate#1086). +for (const [path, name] of [ + ['/leaderboard', 'Chọn ngành hàng'], + ['/compare', 'Chọn danh mục đối chiếu'], +] as const) { + test(`the pressed category stands out in forced colors on ${path}`, async ({ + page, + }) => { + await page.emulateMedia({ forcedColors: 'active' }); + expect((await page.goto(path))?.status()).toBe(200); + const group = page.getByRole('group', { name }); + const look = (pressed: boolean) => + group + .getByRole('button', { pressed }) + .first() + .evaluate((el) => getComputedStyle(el).backgroundColor); + await expect(group.getByRole('button', { pressed: false })).not.toHaveCount( + 0 + ); + expect(await look(true)).not.toBe(await look(false)); + }); +} diff --git a/apps/web/src/app/style/scss/_custom.scss b/apps/web/src/app/style/scss/_custom.scss index 5bc87dfa..9941dc24 100644 --- a/apps/web/src/app/style/scss/_custom.scss +++ b/apps/web/src/app/style/scss/_custom.scss @@ -1522,3 +1522,24 @@ body .input-group > .input-group-text { margin-right: 0 !important; } } + +// Forced colours replace the background and text colours that mark a pressed +// toggle (btn-danger vs btn-outline-dark), so the selected category looked +// like the others in Windows High Contrast. Draw every pressed control with +// the system highlight instead (DOS/Rate#1086). +// `html` outranks Bootstrap's !important utilities (bg-white, text-dark) on +// children such as count badges. +@media (forced-colors: active) { + html [aria-pressed='true'] { + forced-color-adjust: none; + background-color: Highlight !important; + border-color: Highlight !important; + color: HighlightText !important; + + * { + background-color: transparent !important; + border-color: HighlightText !important; + color: HighlightText !important; + } + } +}