<!-- Poor contrast (FAIL) --><p style="color: #777; background: #fff;"> This text has 4.47:1 contrast - FAILS AA for normal text</p><!-- Fixed contrast (PASS AA) --><p style="color: #595959; background: #fff;"> This text has 7.0:1 contrast - PASSES AA and AAA</p><!-- Large text (18pt+) with lower contrast OK --><h2 style="color: #767676; background: #fff; font-size: 24px;"> Large text with 3.01:1 contrast - PASSES AA for large text</h2><!-- Button with sufficient contrast --><button style=" background: #0066cc; color: #fff; border: 2px solid #004499;"> Text: 8.59:1 (PASS), Border: 5.14:1 against background (PASS)</button><!-- Focus indicator with sufficient contrast --><style>.accessible-link:focus { outline: 3px solid #0066cc; /* 3.02:1 against white background */ outline-offset: 2px;}</style><a href="#" class="accessible-link">Accessible focus indicator</a><!-- Icon with sufficient contrast --><svg style="fill: #595959;" role="img" aria-label="Settings"> <!-- Icon with 7:1 contrast against white background --> <path d="M..."></path></svg>
Note: Always test contrast on actual backgrounds. Overlays, gradients, and images can affect
perceived contrast even if colors pass calculation.
2. Color Blind Accessibility Patterns
Color Vision Deficiency
Prevalence
Colors Affected
Design Impact
Protanopia (Red-blind)
~1% males, 0.01% females
Red appears dark, confused with green
Red/green combinations problematic
Deuteranopia (Green-blind)
~1% males, 0.01% females
Green appears beige, confused with red
Red/green combinations problematic
Tritanopia (Blue-blind)
~0.001% all
Blue/yellow confusion
Blue/yellow combinations problematic
Achromatopsia (Total color blindness)
~0.003% all
No color perception (grayscale)
All color-only indicators fail
Example: Color blind friendly patterns
<!-- Bad: Color only for status --><span style="color: red;">Error</span><span style="color: green;">Success</span><!-- Good: Color + icon + text --><span class="status-error"> <svg aria-hidden="true" class="icon">...error icon...</svg> Error: File not found</span><span class="status-success"> <svg aria-hidden="true" class="icon">...checkmark...</svg> Success: File uploaded</span><!-- Bad: Color-only link distinction --><p style="color: #000;"> Visit our <a href="#" style="color: #00f;">website</a> for more info.</p><!-- Good: Underline + color --><p> Visit our <a href="#" style="color: #0066cc; text-decoration: underline;"> website </a> for more info.</p><!-- Good: Form validation with multiple cues --><style>.input-error { border: 2px solid #d32f2f; /* Color */ border-left: 5px solid #d32f2f; /* Extra visual cue */ background: #ffebee; /* Background tint */ background-image: url('error-icon.svg'); /* Icon */ background-position: right 8px center; background-repeat: no-repeat;}</style><input type="email" class="input-error" aria-invalid="true" aria-describedby="email-error"><span id="email-error" class="error-text"> ⚠ Please enter a valid email address</span><!-- Chart with patterns + colors --><style>.chart-bar-1 { fill: #0066cc; stroke-dasharray: none; }.chart-bar-2 { fill: #00897b; stroke-dasharray: 5,5; /* Stripe pattern */}.chart-bar-3 { fill: #f57c00; stroke-dasharray: 2,2; /* Dot pattern */}</style>
Design Strategy
Implementation
Example Use
Use Patterns/Textures
Add stripes, dots, hatching to colored areas
Chart bars, map regions
Add Icons/Symbols
Include visual symbols with color
Status indicators (✓, ✗, ⚠)
Use Shape Differences
Different shapes for categories
Chart markers (●, ■, ▲)
Add Text Labels
Label all colored elements
Chart legends, graph labels
Underline Links
Don't rely on color alone for links
Body text links
Sufficient Brightness Contrast
Ensure luminance difference even if hue fails
All color combinations
Position/Order Cues
Use consistent positioning for status
Traffic lights (red=top, green=bottom)
Example: Color blind friendly color palettes
<!-- Safe color combinations (work for most CVD types) --><style>:root { /* Blue-Orange palette (deuteranopia/protanopia safe) */ --color-primary: #0077bb; /* Blue */ --color-secondary: #ee7733; /* Orange */ --color-accent: #009988; /* Teal */ /* High contrast palette */ --color-dark: #332288; /* Dark purple */ --color-medium: #44aa99; /* Teal */ --color-light: #ddcc77; /* Tan */ /* Status colors with sufficient difference */ --color-success: #117733; /* Dark green */ --color-warning: #ddaa33; /* Gold */ --color-error: #cc3311; /* Red */ --color-info: #0077bb; /* Blue */ /* Avoid these combinations */ /* Red + Green (common CVD issue) */ /* Light green + Yellow */ /* Blue + Purple (for some types) */}/* Sequential data with brightness steps */.data-1 { background: #f7fbff; } /* Lightest */.data-2 { background: #deebf7; }.data-3 { background: #c6dbef; }.data-4 { background: #9ecae1; }.data-5 { background: #6baed6; }.data-6 { background: #4292c6; }.data-7 { background: #2171b5; }.data-8 { background: #08519c; }.data-9 { background: #08306b; } /* Darkest */</style>
Warning:Never use color as the only visual means of conveying
information. Always provide additional cues like text, icons, patterns, or positional differences.
3. High Contrast Mode Support
High Contrast Feature
OS/Browser
CSS Detection
Design Impact
Windows High Contrast
Windows 10/11
@media (prefers-contrast: high)
Overrides all colors with system palette
Increased Contrast
macOS, iOS
@media (prefers-contrast: more)
Suggests stronger contrast
Forced Colors
Windows, browsers
@media (forced-colors: active)
Limited color palette enforced
Inverted Colors
macOS, iOS
@media (inverted-colors: inverted)
All colors inverted
Example: High contrast mode support
<!-- Default styles --><style>.button { background: #0066cc; color: white; border: 2px solid #0066cc; padding: 12px 24px;}/* High contrast mode adjustments */@media (prefers-contrast: high) { .button { border-width: 3px; /* Thicker borders */ font-weight: 600; /* Bolder text */ } /* Ensure focus indicators are extra visible */ .button:focus { outline: 4px solid; outline-offset: 4px; }}/* Forced colors mode (Windows High Contrast) */@media (forced-colors: active) { .button { /* Use system colors instead of custom colors */ background: ButtonFace; color: ButtonText; border-color: ButtonText; } .button:hover { background: Highlight; color: HighlightText; border-color: Highlight; } .button:disabled { color: GrayText; border-color: GrayText; } /* Preserve important visual distinctions */ .icon { /* Force icon to be visible */ forced-color-adjust: auto; } /* Custom focus indicators */ .button:focus { outline: 2px solid ButtonText; outline-offset: 2px; }}/* Inverted colors support */@media (inverted-colors: inverted) { /* Re-invert images/media so they appear normal */ img, video { filter: invert(1); }}/* Increased contrast (macOS/iOS) */@media (prefers-contrast: more) { body { /* Slightly increase base contrast */ } .text-secondary { /* Make secondary text darker */ color: #444; /* Instead of #666 */ }}</style>
System Color Keyword
Use Case
Example
ButtonFace
Button background
background: ButtonFace;
ButtonText
Button text, borders
color: ButtonText;
Canvas
Page background
background: Canvas;
CanvasText
Body text
color: CanvasText;
LinkText
Hyperlinks
color: LinkText;
Highlight
Selected/active background
background: Highlight;
HighlightText
Selected text
color: HighlightText;
GrayText
Disabled text
color: GrayText;
Field
Input background
background: Field;
FieldText
Input text
color: FieldText;
Note: In forced colors mode, custom colors are overridden. Use
forced-color-adjust: none sparingly and only when necessary to preserve critical visual
information.
4. Visual Indicators Beyond Color
Indicator Type
Visual Cue
Use Case
Implementation
Icons
✓ ✗ ⚠ ℹ ★
Status, ratings, actions
SVG or icon fonts with ARIA labels
Text Labels
"Success", "Error", "Required"
All important states
Explicit text with semantic markup
Underlines
Solid, dashed, dotted, double
Links, emphasis, errors
text-decoration
Borders
Thickness, style variations
Focus, active state, errors
border with different widths/styles
Patterns/Textures
Stripes, dots, crosshatch
Charts, graphs, maps
SVG patterns or CSS gradients
Size/Weight
Font size/weight changes
Hierarchy, emphasis
font-size, font-weight
Position/Layout
Spatial arrangement
Navigation state, progress
Flexbox/Grid positioning
Shape
Circle, square, triangle
Chart markers, bullets
SVG or CSS shapes
Example: Multi-sensory status indicators
<!-- Status with icon + color + text --><div class="alert alert-success"> <svg aria-hidden="true" class="alert-icon"> <use href="#checkmark-icon"></use> </svg> <strong>Success:</strong> Your changes have been saved.</div><div class="alert alert-error"> <svg aria-hidden="true" class="alert-icon"> <use href="#error-icon"></use> </svg> <strong>Error:</strong> Unable to connect to server.</div><div class="alert alert-warning"> <svg aria-hidden="true" class="alert-icon"> <use href="#warning-icon"></use> </svg> <strong>Warning:</strong> Your session will expire in 5 minutes.</div><style>.alert { padding: 12px 16px; border-left: 5px solid; /* Thick left border */ display: flex; align-items: flex-start; gap: 12px;}.alert-icon { flex-shrink: 0; width: 24px; height: 24px;}.alert-success { background: #e8f5e9; border-color: #2e7d32; color: #1b5e20;}.alert-success .alert-icon { fill: #2e7d32;}.alert-error { background: #ffebee; border-color: #c62828; color: #b71c1c;}.alert-error .alert-icon { fill: #c62828;}.alert-warning { background: #fff3e0; border-color: #f57c00; color: #e65100;}.alert-warning .alert-icon { fill: #f57c00;}</style><!-- Required field indicators --><label for="email"> Email Address <abbr title="required" aria-label="required" style="color: #d32f2f; text-decoration: none; font-weight: bold;"> * </abbr> <span class="sr-only">(required)</span></label><!-- Link with underline (not just color) --><p> Read our <a href="/privacy" style=" color: #0066cc; text-decoration: underline; text-decoration-thickness: 2px; text-underline-offset: 2px;">privacy policy</a> for details.</p><!-- Progress indicator with multiple cues --><div class="progress-steps"> <div class="step step-completed"> <span class="step-number">1</span> <svg class="step-icon" aria-hidden="true">✓</svg> <span class="step-label">Personal Info</span> </div> <div class="step step-active"> <span class="step-number">2</span> <span class="step-label">Payment</span> </div> <div class="step step-upcoming"> <span class="step-number">3</span> <span class="step-label">Confirmation</span> </div></div>
Warning: WCAG Success Criterion 1.4.1 requires that color is not used as the only visual means of conveying information. Always combine color with at least one
other visual differentiator.
5. CSS Custom Properties for Theming
Theme Aspect
Custom Property Pattern
Use Case
Colors
--color-primary, --color-text
Brand colors, semantic colors
Spacing
--space-sm, --space-md
Consistent spacing scale
Typography
--font-size-base, --line-height
Font sizes, line heights
Shadows
--shadow-sm, --shadow-md
Elevation levels
Borders
--border-radius, --border-width
Consistent borders
Transitions
--transition-fast, --transition-slow
Animation timing
Example: Accessible theming system with CSS custom properties
Note: CSS custom properties can't be used in media queries, but can be changed within them.
Define theme variations inside @media blocks to adapt to user preferences.
Color and Visual Design Quick Reference
Normal text needs 4.5:1 contrast (AA), 7:1 (AAA); large text needs 3:1 (AA), 4.5:1 (AAA)
UI components and graphical objects need minimum 3:1 contrast against adjacent colors
Never use color as the only visual means - add icons, text labels, patterns, or shapes
Avoid red/green combinations - use blue/orange or add patterns/icons for colorblind users
Support high contrast mode with system color keywords (ButtonFace, CanvasText, etc.)
Links must be underlined or have 3:1 contrast with surrounding text
Test designs with color blindness simulators and actual users
Use CSS custom properties for themable, maintainable color systems
Respect prefers-color-scheme and provide manual theme toggle
Ensure focus indicators have 3:1 contrast in all themes (WCAG 2.2)