2.5.6 Level AAA Guideline 2.5 Input Modalities Added in WCAG 2.1 Not detectable automatically

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.

In the specification