fix(a11y): WCAG 1.4.3 — enforce accessible link color contrast#39234
fix(a11y): WCAG 1.4.3 — enforce accessible link color contrast#39234Aitema-gmbh wants to merge 1 commit intoapache:masterfrom
Conversation
…90, 5.62:1 ratio)
| color: #0d7090 !important; | ||
| } | ||
| a:not([class*="ant-btn"]):not([role="button"]):hover { | ||
| color: #0a5a73 !important; |
There was a problem hiding this comment.
Suggestion: These hardcoded link colors bypass the theme token system (colorLink/colorLinkHover) that is used across the app (including dark mode and custom themes), so links will ignore configured palette values and can become inconsistent or low-contrast in non-light themes. Use theme tokens here instead of fixed hex values. [logic error]
Severity Level: Major ⚠️
- ⚠️ Custom themes cannot change non-button link color.
- ⚠️ Dark-mode links may use low-contrast light-theme colors.
- ⚠️ Brand colorPrimary no longer affects standard links.
- ⚠️ A11y token changes not reflected in anchors.| color: #0d7090 !important; | |
| } | |
| a:not([class*="ant-btn"]):not([role="button"]):hover { | |
| color: #0a5a73 !important; | |
| color: ${theme.colorLink}; | |
| } | |
| a:not([class*="ant-btn"]):not([role="button"]):hover { | |
| color: ${theme.colorLinkHover}; |
Steps of Reproduction ✅
1. The global theme provider `Theme.SupersetThemeProvider` renders `<GlobalStyles />` for
every page (see `packages/superset-core/src/theme/Theme.tsx:162-188`), which injects the
CSS from `GlobalStyles.tsx:33-122` including the anchor rules at lines 54-66.
2. The theme system explicitly supports customizing `token.colorLink` independently of
`colorPrimary` (see tests in `packages/superset-core/src/theme/Theme.test.tsx:31-50` and
`52-77`, and the implementation in `Theme.fromConfig`/`Theme.setConfig` at
`Theme.tsx:24-44` and `74-80`, where `colorLink` is derived from or overridden by user
config).
3. Apply a theme configuration where `token.colorLink` is set to a distinct value (for
example `'#ff0000'`) via the real theme API: call `ThemeController.setTheme()`
(implementation at `src/theme/ThemeController.ts:116-123`), which normalizes the config
and ultimately calls `themeObject.setConfig()` (Theme.setConfig) so that
`theme.theme.colorLink` reflects the configured value.
4. Load any Superset page (for example a list or dashboard page) and inspect a standard
text link rendered as an `<a>` element that is not styled as a button (no `class`
containing `"ant-btn"` and no `role="button"`); despite `theme.theme.colorLink` being the
configured color, the computed CSS for that `<a>` shows `color: #0d7090` and hover `color:
#0a5a73` because the rules at `GlobalStyles.tsx:61-65`
(`a:not([class*="ant-btn"]):not([role="button"]) { color: #0d7090 !important; }` and its
`:hover` variant) with `!important` override the earlier token-based rule `a { color:
${theme.colorLink}; }` at lines 54-56, causing non-button links to ignore the configured
theme tokens in all modes (including dark mode and custom themes).Prompt for AI Agent 🤖
This is a comment left during a code review.
**Path:** superset-frontend/packages/superset-core/src/theme/GlobalStyles.tsx
**Line:** 62:65
**Comment:**
*Logic Error: These hardcoded link colors bypass the theme token system (`colorLink`/`colorLinkHover`) that is used across the app (including dark mode and custom themes), so links will ignore configured palette values and can become inconsistent or low-contrast in non-light themes. Use theme tokens here instead of fixed hex values.
Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.There was a problem hiding this comment.
Code Review Agent Run #9bae23
Actionable Suggestions - 1
-
superset-frontend/packages/superset-core/src/theme/GlobalStyles.tsx - 1
- Accessibility regression in dark themes · Line 58-66
Review Details
-
Files reviewed - 1 · Commit Range:
4859f1a..4859f1a- superset-frontend/packages/superset-core/src/theme/GlobalStyles.tsx
-
Files skipped - 0
-
Tools
- Whispers (Secret Scanner) - ✔︎ Successful
- Detect-secrets (Secret Scanner) - ✔︎ Successful
Bito Usage Guide
Commands
Type the following command in the pull request comment and save the comment.
-
/review- Manually triggers a full AI review. -
/pause- Pauses automatic reviews on this pull request. -
/resume- Resumes automatic reviews. -
/resolve- Marks all Bito-posted review comments as resolved. -
/abort- Cancels all in-progress reviews.
Refer to the documentation for additional commands.
Configuration
This repository uses Superset You can customize the agent settings here or contact your Bito workspace admin at evan@preset.io.
Documentation & Help
| /* WCAG 1.4.3: Minimum Contrast — override link color from colorPrimary (#2893B3, | ||
| 3.55:1 on white) to a darker shade that meets the 4.5:1 text contrast threshold. | ||
| Excludes links that are intentionally styled as buttons. */ | ||
| a:not([class*="ant-btn"]):not([role="button"]) { | ||
| color: #0d7090 !important; | ||
| } | ||
| a:not([class*="ant-btn"]):not([role="button"]):hover { | ||
| color: #0a5a73 !important; | ||
| } |
There was a problem hiding this comment.
The hardcoded link colors (#0d7090, #0a5a73) provide good contrast on light backgrounds but fail WCAG 4.5:1 ratio on dark themes where colorBgBase is ~#0a0a0a, resulting in contrast ratios of ~3.47:1 and ~2.5:1 respectively. This breaks accessibility for dark mode users. Consider using CSS custom properties that adapt to the theme or calculating accessible variants dynamically.
Code Review Run #9bae23
Should Bito avoid suggestions like this for future reviews? (Manage Rules)
- Yes, avoid them
SUMMARY
Implements WCAG 2.1 criterion 1.4.3 (Contrast Minimum, Level AA).
colorPrimary(#2893B3, 3.55:1 ratio) to #0d7090 (5.62:1 ratio)[class*="ant-btn"],[role="button"])TESTING INSTRUCTIONS
ADDITIONAL INFORMATION
Part of a series of 16 individual WCAG 2.1 accessibility PRs. See also fix(a11y): Accessibility improvements for WCAG 2.1 Level A compliance #38342.