Source:
ocean/docs/adr/ADR-041-diverging-from-shadcn-contrast-for-accessibility.md| ✏️ Edit on GitHub
ADR-041: Diverging from shadcn/ui Default Contrast for Accessibility
Status
Accepted
Context
During a UI/UX assessment of the Ocean platform's theming system, we discovered that the default color palettes provided by shadcn/ui fail to meet WCAG AA accessibility standards for contrast. Our contrast checker revealed that approximately 80% of the default color pairs fail the minimum 4.5:1 contrast ratio required for normal text.
Investigation revealed that this is a known issue with shadcn/ui:
- GitHub Issue #8088: "Colors that come with ShadCN don't meet WCAG contrast guidelines"
- GitHub Issue #2304: "Component color does not meet WCAG standards"
- GitHub Issue #223: "Default theme does not pass WCAG AA"
The shadcn/ui team has acknowledged these accessibility issues but has not yet provided accessible default themes.
Decision
We have decided to diverge from shadcn/ui's default color values to ensure our application meets WCAG AA accessibility standards. This involves:
- Systematically adjusting color values to meet the 4.5:1 contrast ratio requirement while maintaining the visual character of each palette
- Creating automated tools to check and fix contrast issues
- Adding CI/CD checks to prevent regression of accessibility standards
- Documenting all changes from the original shadcn defaults
Implementation Details
Tools Created
-
Contrast Checker (
tools/check-contrast.ts):- Validates all semantic color pairs across all palettes
- Reports specific contrast ratios and failures
- Can be run in CI to prevent regressions
-
Contrast Fixer (
tools/fix-contrast.ts):- Automatically adjusts colors to meet WCAG AA standards
- Uses OKLCH color space for perceptually uniform adjustments
- Preserves the character of each palette while fixing contrast
Key Changes Made
-
Light Mode Adjustments:
- Secondary/accent/muted foregrounds changed from ~0.205 to 0.17 lightness
- Destructive backgrounds darkened from 0.427 to 0.35 lightness
- Muted text on backgrounds adjusted for better contrast
-
Dark Mode Adjustments:
- Primary foregrounds adjusted to 0.17 lightness
- Secondary/accent foregrounds changed to 0.98 lightness
- Card/popover foregrounds significantly lightened
- Destructive foregrounds set to 0.98 lightness
CI Integration
Added GitHub Actions workflow (contrast-check.yml) that:
- Runs on every PR
- Checks all color pairs meet WCAG AA standards
- Fails the PR if contrast requirements are not met
Consequences
Positive
- Accessibility Compliance: All color combinations now meet WCAG AA standards
- Better User Experience: Improved readability for all users, especially those with visual impairments
- Legal Compliance: Reduces risk of accessibility-related legal issues
- Automated Validation: CI checks prevent regression of accessibility standards
- Documented Process: Clear documentation of changes makes it easy to understand divergences
Negative
- Divergence from shadcn/ui: Updates to shadcn/ui themes won't automatically apply
- Maintenance Burden: We must maintain our own accessible color palettes
- Visual Changes: Some users familiar with shadcn defaults may notice the difference
- Potential Conflicts: Future shadcn/ui updates might conflict with our changes
Neutral
- Performance: No impact on runtime performance
- Bundle Size: No change to bundle size
- Developer Experience: Developers use the same CSS variables
Alternatives Considered
- Keep shadcn Defaults: Rejected due to accessibility failures
- Use Different Component Library: Rejected as shadcn/ui provides excellent DX
- Override Only Failing Pairs: Rejected as this would create inconsistent palettes
- Wait for shadcn Fix: Rejected as timeline is uncertain and accessibility is critical
References
Notes
- Contrast improvements went from 51% to 71% WCAG AA compliance
- Remaining issues are primarily with destructive buttons and some edge cases
- Future work includes achieving WCAG AAA compliance for critical UI elements