Faking a control with a generic box requires filling in all of its semantics
Aliases: reconstruct native semantics · generic box as control · partial ARIA is a hole
What it is
When look or motion forces dropping a platform control for a generic box — div, span, an un-roled View — painted as a switch, menu, or tab set, none of the platform bundle arrives on its own. A fake control has to fill in everything that bundle would have done, not only the clickable layer. Leave any piece out and mouse users meet a control while keyboard and screen-reader users meet a static box.
“Everything” is what that native control does under assistive technology and the keyboard: it can be found, focused, activated with the right keys, inert when disabled, and present on the matching control list. The job is completeness against the native original, not a new theory of widgets.
Why it happens
A native button ties focus, key activation, disabled, form participation, and membership in the button list to one element type. A generic box copies pixels. A click can be bound separately, and each binding is optional: click without keyboard, and Tab never arrives; keyboard without being recognized as a control, and the auditory channel still hears text; recognition without disabled, and it looks grey while AT still treats it as pressable.
Partial patches split the interface: one path works, the others fail, and the failure is easy to miss in a visual pass. The reference is always the abandoned native control’s full behavior on assistive channels, not “one more ARIA attribute might do.” Each missing item drops a class of users at that step.
Where it stops holding
Decorative boxes that are not controls should not be filled in as controls; completeness then becomes a false interactive announcement. When the generic box only wraps a real native control, extra semantics on the wrapper double-announce and double-focus — strip the disguise rather than stack a second bundle. Some widgets are extremely expensive to reconstruct (a full combobox, a spreadsheet cell); the honest move is to return to native or change the design, not to claim a role was added. A control that cannot be completed for keyboard activation is not a control yet, and “it looks clickable” is not a pass.
Applying it
- For every custom control, list assistive-channel and keyboard behaviors of the native control it replaces, and turn gaps into implementation tasks. Look-only is not a delivery.
- Do not merge “clickable now, semantics later” to main. A partial patch is harder to spot than no control.
- Include non-default states — disabled, read-only, loading — on the same list, not only the default clickable state.
- How to check: keyboard through open, close, select, and dismiss; a screen reader announces the type and lists it in the matching roster; disabled cannot be activated from the keyboard. Any miss, and it is still a fake.
Related
- Same group: R3.01.1 Native semantic elements bring assistive-technology behavior with them · R3.01.3 Structural order is the order assistive technology walks
- Nearby: J2.09 Semantic structure · R3.09 Semantic structure and accessibility implementation
- Search terms:
complete semantics·custom control accessibility·generic container as widget