Error states indicated only by a red border, status indicated only by a green/red dot, and form field requirements indicated only by an asterisk colored red — all three convey meaning exclusively through color. Approximately 8% of men and 0.5% of women have some degree of red-green color vision deficiency; for them, red and green may appear as identical shades of brown. WCAG 2.2 SC 1.4.1 (Use of Color) explicitly prohibits color as the sole visual means of conveying information. Section 508 2018 Refresh 302.7 enforces visual accessibility. The concrete failure: a form with red-bordered invalid fields shows no error text — a user with protanopia sees a border of indeterminate color and has no way to identify the problem or its nature.
Medium because color-only indicators exclude users with color vision deficiencies from understanding critical state information like form errors or required fields.
Every color-coded status must be accompanied by a text label, icon, pattern, or structural cue. In form validation, this means visible error text — not just a colored border.
// Bad: Red border with no text
<input
type="email"
style={{ borderColor: hasError ? 'red' : 'gray' }}
/>
// Good: Border + icon + text
<div className="field">
<label htmlFor="email">Email</label>
<div className="input-wrapper">
<input
id="email"
type="email"
aria-invalid={hasError}
aria-describedby={hasError ? 'email-error' : undefined}
className={hasError ? 'border-red-600' : 'border-gray-300'}
/>
{hasError && <ErrorIcon aria-hidden="true" />}
</div>
{hasError && (
<p id="email-error" className="text-red-700">
{/* Text conveys the error — color reinforces it */}
Please enter a valid email address.
</p>
)}
</div>
For status indicators (online/offline, success/error), always pair the color with text or an icon with an accessible label:
// Bad
<span className="bg-green-500 rounded-full w-3 h-3" />
// Good
<span className="flex items-center gap-1">
<span className="bg-green-500 rounded-full w-3 h-3" aria-hidden="true" />
<span className="text-sm">Online</span>
</span>
ID: accessibility-basics.visual-color.color-not-sole-indicator
Severity: medium
What to look for: Enumerate every relevant item. Look for information conveyed only by color (e.g., "required fields in red", "errors in red", "success in green"). Check whether the same information is also conveyed via text, icons, patterns, or other non-color cues.
Pass criteria: At least 1 of the following conditions is met. Information conveyed by color also includes text labels, icons, patterns, or other visual cues. Users who cannot distinguish colors can still understand the information.
Fail criteria: Information is conveyed by color alone with no alternative cue (e.g., a red border on an error field but no error message text).
Skip (N/A) when: Never — color accessibility applies to all visual designs.
Detail on fail: Identify color-only indicators. Example: "Required form fields indicated by red asterisk only. No text '(Required)'. Error fields have red border only; no error message text."
Remediation: Always pair color with text, icons, or patterns:
{/* Bad: Color only */}
<input style={{ borderColor: error ? 'red' : 'gray' }} />
{/* Good: Color + text + icon */}
<div>
<label>
Email <span style={{ color: 'red' }}>*</span>
</label>
<input type="email" required />
{error && <p style={{ color: 'red' }}>Error: {error.message}</p>}
</div>
{/* Good: Color + pattern */}
<div style={{ borderLeft: `4px solid ${error ? 'red' : 'green'}` }}>
{error && <AlertIcon />}
{error ? 'Error' : 'Success'}
</div>