What FormEngine gives you out of the box
When you use FormEngine with a ready-made UI pack (React Suite, Material UI, Mantine), you inherit these accessibility behaviors for free:- Semantic HTML — inputs, labels, and form elements render as real
<input>,<label>,<select>,<button>tags - Keyboard navigation — Tab, Shift+Tab, Enter, Escape behavior matches native HTML controls
- Focus management — required fields focus on validation failure; modals trap focus
- ARIA attributes —
aria-required,aria-invalid,aria-describedbyare set when appropriate - Label association — the
labelprop wireshtmlForcorrectly to each input’sid
required validation rule automatically adds aria-required="true" and a required CSS class. See Required property.
What you need to add
1. Provide meaningful labels
Every field needs a visible label or anaria-label. Placeholder text is not a substitute for a label.
aria-label:
2. Describe complex fields
For fields with format requirements or constraints, add a description that screen readers read alongside the label:<p id="password-hint">Minimum 8 characters, one number.</p> near the field. Or use FormEngine’s Tooltip component, which wires aria-describedby automatically.
3. Announce validation errors to screen readers
Put form-level error messages inside a live region so screen readers announce them on change:role="alert" — check your pack’s implementation or wrap errors in a live region yourself.
4. Manage focus on validation failure
When a user submits and validation fails, move focus to the first invalid field:5. Give buttons clear action labels
Avoid generic labels like “Submit” or “OK” for forms with multiple actions. Use specific action verbs:6. Don’t rely on color alone
Validation state must be communicated by more than color. FormEngine UI packs add icons andaria-invalid alongside red borders — if you build custom components, do the same:
Keyboard support
FormEngine forms inherit keyboard behavior from the underlying UI library. Minimum expectations:- Tab / Shift+Tab — move between fields in source order
- Space / Enter — activate buttons and checkboxes
- Enter inside a text input — submit the form (if a submit button exists)
- Escape — close open dropdowns, date pickers, modals
- Arrow keys — navigate within radio groups, select lists, date pickers
Screen reader testing
At minimum, test with:- NVDA (free, Windows) + Firefox or Chrome
- VoiceOver (built-in, macOS) + Safari
- JAWS (commercial, Windows) + Edge or Chrome if you target enterprise
WCAG 2.1 AA checklist for forms
- Every input has a programmatically associated label
- Required fields are marked both visually and via
aria-required - Error messages are associated with their fields via
aria-describedby - Error messages are in a live region or announced via
role="alert" - Focus moves to the first invalid field on failed submit
- Color contrast is at least 4.5:1 for text, 3:1 for UI components
- Validation state is shown with more than color alone
- All controls are reachable and operable by keyboard
- Focus is visible on every interactive element
- No keyboard traps (Escape closes modals, focus returns to trigger)
- Form works at 200% zoom without horizontal scrolling
- Timeout warnings (if any) give users a way to extend the session
Custom components: accessibility requirements
If you build custom components, you own their accessibility. Minimum:- Use semantic HTML (
<button>, not<div onClick>) - Accept and apply
id,aria-*,disabled,requiredprops - Handle keyboard events (
onKeyDownfor custom interactions) - Provide visible focus styles
- Announce state changes via
aria-livewhere appropriate
Automated testing
Automated tools catch 30-40% of a11y issues. Use them as a baseline, not a substitute for manual testing.- axe-core — integrate via
@axe-core/reactin dev orjest-axein tests - Lighthouse — built into Chrome DevTools
- pa11y — CI-friendly a11y scanner
Related
- Required property — automatic
aria-requiredhandling - Tooltips —
aria-describedbyintegration - Testing guide — integration tests including axe
- Custom components — build accessible custom fields