-
Notifications
You must be signed in to change notification settings - Fork 41
Description
Accessibility Checklist for Solid-UI Theme System
Date: January 15, 2026
Scope: WCAG 2.1 Level AA Compliance
Related: Theme System Analysis
Overview
This checklist ensures the theme system implementation meets WCAG 2.1 Level AA accessibility standards, making Solid applications usable by people with disabilities including visual, auditory, motor, and cognitive impairments.
Phase 1: Foundation (Weeks 1-2)
✅ Color & Contrast
-
Color Contrast Ratios (WCAG 2.1 - 1.4.3)
- Normal text: Minimum 4.5:1 contrast ratio
- Large text (18pt+): Minimum 3:1 contrast ratio
- UI components: Minimum 3:1 contrast ratio
- Test all theme color combinations
- Document contrast ratios for each theme
-
Color Independence (WCAG 2.1 - 1.4.1)
- Information not conveyed by color alone
- Use icons + text labels together
- Error states use icons, not just red color
- Success states use icons, not just green color
-
High Contrast Mode (WCAG 2.1 - 1.4.6)
- Implement
@media (prefers-contrast: high)support - Test with Windows High Contrast Mode
- Borders visible in high contrast
- Focus indicators work in high contrast
- Implement
✅ Typography & Readability
-
Text Resize (WCAG 2.1 - 1.4.4)
- Text resizable up to 200% without loss of functionality
- Use relative units (em, rem) instead of px
- Test at 200% zoom in browser
- No horizontal scrolling at 200% zoom
-
Font Choices
- Use readable sans-serif fonts (Inter, Roboto)
- Minimum 16px base font size
- Line height at least 1.5x font size
- Paragraph spacing at least 1.5x line height
-
Reduced Motion (WCAG 2.1 - 2.3.3)
- Implement
@media (prefers-reduced-motion: reduce) - Disable animations when user prefers reduced motion
- Provide instant theme switching option
- Test with motion preference enabled
- Implement
✅ Focus Management
-
Visible Focus Indicators (WCAG 2.1 - 2.4.7)
- Focus outline visible on all interactive elements
- Focus outline minimum 2px width
- High contrast between focus and background
- Focus outline not obscured by content
- Custom focus styles meet 3:1 contrast ratio
-
Focus Order (WCAG 2.1 - 2.4.3)
- Logical tab order (left to right, top to bottom)
- Theme switcher in logical position
- Skip to main content link provided
- No keyboard traps
-
Focus Visible (CSS)
/* Example implementation */ :focus-visible { outline: 2px solid var(--sui-focus-color); outline-offset: 2px; } /* Don't hide focus for keyboard users */ :focus:not(:focus-visible) { outline: none; }
✅ CSS Variables for Accessibility
/* src/themes/foundation/accessibility.css */
:root {
/* Focus indicators */
--sui-focus-color: #667eea;
--sui-focus-width: 2px;
--sui-focus-offset: 2px;
/* Minimum touch targets */
--sui-touch-target-min: 44px;
/* Readable text */
--sui-line-height: 1.5;
--sui-paragraph-spacing: 1.5em;
}
/* High contrast mode */
@media (prefers-contrast: high) {
:root {
--sui-border: #000;
--sui-text: #000;
--sui-bg: #fff;
--sui-focus-color: #000;
}
}
/* Reduced motion */
@media (prefers-reduced-motion: reduce) {
*,
*::before,
*::after {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
}
}Phase 2: Components (Weeks 3-4)
✅ Theme Switcher Widget
-
Keyboard Accessible (WCAG 2.1 - 2.1.1)
- Operable with keyboard only
- Space/Enter to activate
- Arrow keys to navigate options
- Escape to close if dropdown
-
ARIA Attributes
<select id="theme-switcher" aria-label="Choose color theme" aria-describedby="theme-help"> <option value="classic">Classic</option> <option value="solid">Solid</option> <option value="wave">Wave</option> <option value="telegram">Telegram</option> </select> <span id="theme-help" class="sr-only"> Changes the color scheme of the application </span>
-
Change Announcements
- Announce theme change to screen readers
- Use ARIA live region
- Polite announcement (not assertive)
✅ Buttons & Interactive Elements
-
Button Accessibility (WCAG 2.1 - 4.1.2)
- Use semantic
<button>elements - Descriptive accessible names
- Disabled state communicated to screen readers
- Loading state announced
- Use semantic
-
Touch Target Size (WCAG 2.1 - 2.5.5)
- Minimum 44x44px touch targets
- Adequate spacing between targets
- Test on mobile devices
-
ARIA for Buttons
<!-- Standard button --> <button type="button" aria-label="Save changes"> 💾 </button> <!-- Toggle button --> <button type="button" role="switch" aria-checked="false" aria-label="Dark mode"> Toggle </button> <!-- Button with loading state --> <button type="button" aria-busy="true" aria-label="Saving..."> Saving... </button>
✅ Form Controls
-
Labels (WCAG 2.1 - 1.3.1, 3.3.2)
- All inputs have associated labels
- Label text describes purpose
- Use
<label for="id">or aria-label - Required fields marked
-
Error Messages (WCAG 2.1 - 3.3.1, 3.3.3)
- Errors clearly identified
- Error descriptions provided
- Errors associated with fields (aria-describedby)
- Error summary at top of form
-
Input Validation
<div class="form-field"> <label for="username">Username *</label> <input id="username" type="text" aria-required="true" aria-invalid="false" aria-describedby="username-error username-hint"> <span id="username-hint" class="hint"> Must be 3-20 characters </span> <span id="username-error" role="alert" class="error" hidden> Username is required </span> </div>
✅ Chat Components
-
Message List (WCAG 2.1 - 1.3.1)
- Semantic list markup (
<ul>,<li>) - Messages have role="article" or similar
- Timestamps readable by screen readers
- Author names clearly associated
- Semantic list markup (
-
Live Regions (WCAG 2.1 - 4.1.3)
- New messages announced
- Use
aria-live="polite"for chat - Use
aria-live="assertive"for alerts - Limit announcement frequency
-
Chat Accessibility
<div class="chat-container" role="log" aria-label="Chat messages"> <ul class="messages" aria-live="polite" aria-atomic="false"> <li class="message" role="article"> <img src="avatar.jpg" alt="John Doe" class="avatar"> <div class="message-content"> <span class="author">John Doe</span> <time datetime="2026-01-15T10:30:00">10:30 AM</time> <p>Hello world!</p> </div> </li> </ul> </div> <!-- Announcement for screen readers only --> <div role="status" aria-live="polite" class="sr-only"> New message from John Doe: Hello world! </div>
✅ Dialogs & Modals
-
Dialog Accessibility (WCAG 2.1 - 2.4.3)
- Use
role="dialog"orrole="alertdialog" - aria-labelledby for title
- aria-describedby for description
- Focus trapped inside dialog
- Escape key closes dialog
- Focus returns to trigger on close
- Use
-
Modal Implementation
<div role="dialog" aria-modal="true" aria-labelledby="dialog-title" aria-describedby="dialog-desc"> <h2 id="dialog-title">Confirm Action</h2> <p id="dialog-desc">Are you sure you want to proceed?</p> <button type="button">Cancel</button> <button type="button">Confirm</button> </div>
Phase 3: Advanced Patterns (Weeks 5-6)
✅ Complex Widgets
-
Tabs (WCAG 2.1 - 4.1.2)
- role="tablist" on container
- role="tab" on tab buttons
- role="tabpanel" on panels
- aria-selected on active tab
- Arrow key navigation
-
Accordions
- Semantic heading structure
- Button triggers with aria-expanded
- aria-controls linking
- Keyboard navigation
-
Menus
- role="menu" and role="menuitem"
- Arrow key navigation
- Home/End key support
- Escape to close
✅ Dynamic Content
-
Loading States (WCAG 2.1 - 4.1.3)
- aria-busy="true" during loading
- Loading message announced
- Skeleton screens have aria-label
- Spinners have accessible names
-
Infinite Scroll
- Announce loading more items
- "Load More" button alternative
- Total count provided
- Progress indicated
✅ Landmark Regions
-
Page Structure (WCAG 2.1 - 2.4.1)
-
<header>or role="banner" -
<nav>or role="navigation" -
<main>or role="main" -
<aside>or role="complementary" -
<footer>or role="contentinfo"
-
-
Skip Links
<a href="#main-content" class="skip-link"> Skip to main content </a> <a href="#navigation" class="skip-link"> Skip to navigation </a> <style> .skip-link { position: absolute; top: -40px; left: 0; background: var(--sui-primary); color: white; padding: 8px; z-index: 100; } .skip-link:focus { top: 0; } </style>
Phase 4: Testing & Validation (Week 7)
✅ Automated Testing
-
axe DevTools
- Run on all pages
- Fix all critical issues
- Document known issues
- Regular CI/CD checks
-
WAVE
- Check each theme
- Verify contrast ratios
- Check structure
- Validate ARIA
-
Lighthouse
- Accessibility score > 95
- All categories checked
- Performance impact minimal
✅ Manual Testing
-
Keyboard Navigation
- Tab through all interactive elements
- No keyboard traps
- Visible focus at all times
- Logical tab order
- All actions keyboard accessible
-
Screen Reader Testing
- NVDA (Windows - free)
- JAWS (Windows - commercial)
- VoiceOver (Mac - built-in)
- TalkBack (Android)
- VoiceOver (iOS)
-
Screen Reader Checklist
- All content readable
- Headings properly nested
- Links descriptive
- Forms properly labeled
- Dynamic updates announced
- Images have alt text
-
Browser Testing
- Chrome + ChromeVox
- Firefox
- Safari
- Edge
- Mobile browsers
✅ Visual Testing
-
Zoom Testing
- 200% zoom without horizontal scroll
- 400% zoom still usable
- Text doesn't overlap
- All content accessible
-
Color Blindness
- Test with color blindness simulators
- Deuteranopia (red-green)
- Protanopia (red-green)
- Tritanopia (blue-yellow)
- Information not color-dependent
✅ User Testing
-
Real Users with Disabilities
- Screen reader users
- Keyboard-only users
- Low vision users
- Cognitive disability users
- Motor disability users
-
Feedback Collection
- Document issues found
- Prioritize fixes
- Iterate and retest
- Continuous improvement
Testing Tools & Resources
Browser Extensions
- axe DevTools - https://www.deque.com/axe/devtools/
- WAVE - https://wave.webaim.org/extension/
- Accessibility Insights - https://accessibilityinsights.io/
- Color Contrast Analyzer - Chrome/Firefox
Screen Readers
- NVDA (Free) - https://www.nvaccess.org/
- JAWS (Commercial) - https://www.freedomscientific.com/products/software/jaws/
- VoiceOver (Built-in Mac/iOS)
- TalkBack (Built-in Android)
Testing Services
- axe Monitor - Automated accessibility monitoring
- UsableNet - Accessibility testing platform
- Tenon.io - API-based accessibility testing
Documentation
- WCAG 2.1 - https://www.w3.org/WAI/WCAG21/quickref/
- ARIA Authoring Practices - https://www.w3.org/WAI/ARIA/apg/
- WebAIM - https://webaim.org/
- A11y Project - https://www.a11yproject.com/
Screen Reader Only (SR-Only) Utility
/* Visually hidden but accessible to screen readers */
.sr-only {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
white-space: nowrap;
border-width: 0;
}
/* Focusable when navigated to via keyboard */
.sr-only-focusable:focus {
position: static;
width: auto;
height: auto;
padding: inherit;
margin: inherit;
overflow: visible;
clip: auto;
white-space: normal;
}Success Criteria
Phase 1 (Foundation)
- ✅ All color contrasts meet WCAG AA (4.5:1 minimum)
- ✅ Focus indicators visible on all interactive elements
- ✅ Reduced motion preference respected
- ✅ High contrast mode supported
Phase 2 (Components)
- ✅ All form fields properly labeled
- ✅ Theme switcher fully keyboard accessible
- ✅ ARIA attributes correct and validated
- ✅ Touch targets minimum 44x44px
Phase 3 (Advanced)
- ✅ Complex widgets follow ARIA patterns
- ✅ Dynamic content updates announced
- ✅ Landmark regions properly defined
- ✅ Skip links functional
Phase 4 (Testing)
- ✅ axe DevTools: 0 critical issues
- ✅ Lighthouse accessibility: >95 score
- ✅ Manual keyboard testing: 100% pass
- ✅ Screen reader testing: 100% pass
- ✅ User testing: Positive feedback
Ongoing Maintenance
-
Regular Audits
- Quarterly accessibility reviews
- Update with new WCAG guidelines
- Monitor user feedback
- Fix issues promptly
-
Documentation
- Maintain accessibility guide
- Document known limitations
- Provide VPAT (Voluntary Product Accessibility Template)
- Update as features change
-
Training
- Developer accessibility training
- QA accessibility testing training
- Design accessibility guidelines
- Continuous education
Status: Draft for Implementation
Last Updated: January 15, 2026
Next Review: After Phase 1 completion