Accessible disabled-state design
Disabled doesn't mean invisible. A systematic approach to communicating unavailability without breaking assistive tech or frustrating power users.
The rule
Never remove a disabled control from the tab order. Use aria-disabled instead of the HTML disabled attribute when the user needs to understand why something is unavailable.
Visuals
- Opacity 40–50% on the control surface, never on the label.
- Cursor: not-allowed only on interactive regions.
- Tooltip on hover/focus explaining the precondition.
Copy
Pair the disabled state with a one-line reason. “Save changes” becomes “Save changes — resolve 2 errors above.” The helper text must be reachable via aria-describedby.
Testing
Rotate through VoiceOver, NVDA, and keyboard-only navigation. Confirm the disabled control receives focus, announces its label and reason, and does not respond to Enter/Space.
Meridian tip: Our form primitives ship with a reason prop that wires aria-describedby automatically.