Skip to content

fix(a11y): WCAG 1.4.3 — enforce accessible link color contrast#39234

Open
Aitema-gmbh wants to merge 1 commit intoapache:masterfrom
Aitema-gmbh:fix/wcag-1.4.3-contrast-minimum
Open

fix(a11y): WCAG 1.4.3 — enforce accessible link color contrast#39234
Aitema-gmbh wants to merge 1 commit intoapache:masterfrom
Aitema-gmbh:fix/wcag-1.4.3-contrast-minimum

Conversation

@Aitema-gmbh
Copy link
Copy Markdown

SUMMARY

Implements WCAG 2.1 criterion 1.4.3 (Contrast Minimum, Level AA).

  • Override default link color from colorPrimary (#2893B3, 3.55:1 ratio) to #0d7090 (5.62:1 ratio)
  • Scope override to exclude button-styled links ([class*="ant-btn"], [role="button"])
  • Hover state uses #0a5a73 for consistent contrast

TESTING INSTRUCTIONS

  1. Open any page with links → links should be darker blue (#0d7090)
  2. Buttons styled as links should retain their original styling
  3. Use a contrast checker → all text links should meet 4.5:1 minimum

ADDITIONAL INFORMATION

@dosubot dosubot bot added change:frontend Requires changing the frontend design:accessibility Related to accessibility standards labels Apr 9, 2026
Comment on lines +62 to +65
color: #0d7090 !important;
}
a:not([class*="ant-btn"]):not([role="button"]):hover {
color: #0a5a73 !important;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.
Suggested change
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.
👍 | 👎

Copy link
Copy Markdown
Contributor

@bito-code-review bito-code-review bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

AI Code Review powered by Bito Logo

Comment on lines +58 to +66
/* 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;
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Accessibility regression in dark themes

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

change:frontend Requires changing the frontend design:accessibility Related to accessibility standards packages size/S

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant