Accessibility guidelines
WCAG 2.2 AA standards for semantic HTML, keyboard access, ARIA, forms, and contrast — with or without Duo.
Accessibility guidelines
Accessible interfaces work for keyboard-only users, screen reader users, and people with low vision or color-vision differences. Follow WCAG 2.2 AA by default.
Install the standalone agent skill for AI-assisted work: npx skills add https://design.talentech.io → choose accessible-frontend.
Core principles
Semantic HTML first
- Use native HTML elements (
<button>,<nav>,<main>,<article>,<dialog>) instead of<div>or<span>with click handlers. - Use correct heading hierarchy (
<h1>through<h6>) without skipping levels.
Keyboard accessibility
- All interactive elements must be focusable and operable via keyboard (Tab, Enter, Space, Arrows).
- Provide visible focus indicators (
:focus-visible). Never useoutline: nonewithout a custom focus style.
ARIA
- Rule of thumb: No ARIA is better than bad ARIA. Use native HTML elements whenever possible.
- Use
aria-labeloraria-labelledbywhen a visual label is missing. - Use
aria-expanded,aria-hidden,aria-controls, andaria-livefor dynamic content and state changes.
Color and contrast
- Ensure text has a contrast ratio of at least 4.5:1 for normal text and 3:1 for large text.
- Do not rely on color alone to convey information — combine with icons or text for errors, success, and status.
Forms and inputs
- Every
<input>,<select>, and<textarea>must have an associated<label>. - Use
aria-describedbyto link inputs to error messages or helper text. - Group related radio buttons and checkboxes with
<fieldset>and<legend>.
See also Form guidelines and Error messages.
Images and media
- Provide meaningful
alttext for informative images. - Use
alt=""for purely decorative images so screen readers ignore them.
Examples
Button
<!-- Bad --><div class="btn" onclick="submitForm()">Submit</div>
<!-- Good --><button type="submit" class="btn">Submit</button>Form input with error
<!-- Bad --><input type="text" placeholder="Email address" /><span class="error">Invalid email</span>
<!-- Good --><label for="email">Email address</label><input type="email" id="email" aria-describedby="email-error" aria-invalid="true" /><span id="email-error" class="error" role="alert">Invalid email format</span>Icon button
<!-- Bad --><button><svg>...</svg></button>
<!-- Good --><button aria-label="Close dialog"><svg aria-hidden="true">...</svg></button>Modal / dialog
<dialog aria-labelledby="dialog-title" aria-modal="true"> <h2 id="dialog-title">Confirm Action</h2> <p>Are you sure you want to proceed?</p> <button autofocus>Confirm</button> <button>Cancel</button></dialog>Navigation
<nav aria-label="Main navigation"> <ul> <li><a href="/" aria-current="page">Home</a></li> <li><a href="/about">About</a></li> </ul></nav>Review checklist
Before shipping frontend code, verify:
- All interactive elements are native or properly role-assigned
- Component is fully operable with keyboard only
- Focus states are clearly visible
- All inputs have associated labels
- Dynamic state changes are announced to screen readers
- Color contrast meets 4.5:1 (normal text) or 3:1 (large text)
- Images have appropriate
alttext - No color is used as the sole indicator of meaning
With Duo
When building with the Duo Design System:
- Prefer
<duo-*>web components over bespoke markup for standard patterns — they ship keyboard support, focus styles, and accessible names. - Use
<duo-field>with native controls in the light DOM; follow markup order in Form guidelines. - Set accessible names on icon-only controls (
aria-labelon<duo-button>,accessibleLabelwhere documented). - Use semantic design tokens (
var(--duo-*)) for focus and state — not hardcoded colors. - Check each component’s accessibility section under Components.
Install Duo agent skills: npx skills add https://design.talentech.io → choose build-with-duo and audit-duo-conformance. Add accessible-frontend for broader WCAG coverage beyond Duo patterns.