Concurrent Input Mechanisms
Content does not restrict use of input modalities available on a platform, except where necessary for security or to respect user settings.
Who this affects
Users who switch between touch, keyboard, and mouse within a single session — common for users with fluctuating conditions and for anyone on a 2-in-1 device.
The failure and the fix
Each example below is a self-contained page, loaded in a frame so its markup cannot affect this page. Open either one on its own to test it with a keyboard or screen reader.
Fails 2.5.6
Open the failing example in a new tab
fail.html — the problem
<h1>Reading list</h1>
<!-- FAILURE: the page sniffs for touch support once, at load, and then binds
ONLY touch handlers. On a 2-in-1 laptop, a tablet with a keyboard case, or
a touchscreen desktop, the keyboard and mouse stop working.
Who this breaks: someone with a fluctuating condition who uses touch in
the morning and a keyboard when their hands are tired; someone who uses a
stylus for precision and a keyboard for text; anyone who plugs a keyboard
into a tablet.
The bug behind it is the assumption that input capability is a fixed
property of a DEVICE. It is a property of the MOMENT. -->
<p id="mode"></p>
<ul class="plain" id="list">
<li><button type="button" class="button button--secondary" data-t="Tidal Flats">Tidal Flats</button></li>
<li><button type="button" class="button button--secondary" data-t="The Long Field">The Long Field</button></li>
</ul>
<p id="picked" role="status"></p>
Meets 2.5.6
Open the passing example in a new tab
pass.html — the fix
<h1>Reading list</h1>
<!-- FIX: no device sniffing at all. A real button plus a click handler works
with touch, mouse, stylus, keyboard, switch and voice control
simultaneously, because the browser normalises all of them into `click`.
The rule: bind to `click`, not to `touchstart` or `mousedown`. Use
`pointer*` events if you need low-level pointer data, and never remove a
control from the tab order because you think the user does not need it. -->
<ul class="plain" id="list">
<li><button type="button" class="button button--secondary" data-t="Tidal Flats">Tidal Flats</button></li>
<li><button type="button" class="button button--secondary" data-t="The Long Field">The Long Field</button></li>
</ul>
<p id="picked" role="status">Nothing selected yet.</p>
<!-- If you must adapt the INTERFACE to input type - larger targets once a
touch has been seen, say - respond to the most recent interaction rather
than to a capability check at load, and never disable another path:
window.addEventListener('pointerdown', function (e) {
document.body.dataset.lastInput = e.pointerType; // touch | mouse | pen
});
window.addEventListener('keydown', function () {
document.body.dataset.lastInput = 'keyboard';
});
That adapts presentation without ever taking an input method away.
The permitted exceptions are narrow: restricting input where it is
necessary for SECURITY, or to respect a setting the user themselves chose. -->
How to test it
Switch input methods mid-task. A site that detects touch and disables keyboard handlers, or vice versa, fails.
-
Automated
Requires testing with multiple input devices on the same session.
No axe rule maps to this criterion. It has to be checked by a person.
-
Keyboard
Unplug the mouse. Move through the page with Tab, Shift+Tab, Enter, Space and the arrow keys. See the keyboard testing script.
-
Screen reader
Listen to both examples with NVDA, JAWS, VoiceOver or TalkBack and compare what is announced. See the screen reader cheat sheets.
-
Visual
Zoom to 200% and 400%, narrow the viewport to 320 px, and apply the text-spacing overrides. See the visual testing procedures.
Related criteria
In the specification
- Understanding 2.5.6 Concurrent Input Mechanisms — the W3C explanation, intent and exceptions
- 2.5.6 in the WCAG 2.2 Recommendation — the normative wording
WCAG 2.2 Demo Suite