No keyboard trap


Description

This rule checks for keyboard traps. This includes use of both standard and non-standard keyboard navigation to navigate through all content without becoming trapped.

Applicability

The rule only applies to any HTML or SVG element that is focusable.

Note: This rule only applies to HTML and SVG. Thus, it is a partial check for WCAG 2.0 success criterion 2.1.2, which applies to all content.

Expectation

For each test target, the outcome of one of the following rules is "passed":

Assumptions

There are currently no assumptions.

Accessibility Support

There are no major accessibility support issues known for this rule.

Background

Test Cases

Passed

Passed Example 1

No trap for keyboard navigation.

<a href="#">Link 1</a> <button class="target">Button1</button>

Passed Example 2

Using tabindex="1".

<div tabindex="1">Text</div>

Passed Example 3

Using tabindex="-1".

<div tabindex="-1">Text</div>

Passed Example 4

Keyboard trap with help information in a paragraph before, and where the method advised works.

<script>
	var trapOn = false
</script>

<p>Press the M-key to Exit</p>
<a id="link1" href="#">Link 1</a>
<button id="btn1" onblur="(function(e){trapOn=true; document.getElementById('btn2').focus();})(event)">
	Button 1
</button>
<button
	id="btn2"
	class="target"
	onkeydown="(function(e){ if (e.keyCode === 77){trapOn=false;document.getElementById('link2').focus();}})(event)"
	onblur="(function(e){ if(trapOn){document.getElementById('btn1').focus();}})(event)"
>
	Button 2
</button>
<a id="link2" href="#">Link 2</a>

Passed Example 5

Keyboard trap with help information within the trap, and where the method advised works.

<script>
	var trapOn = false
</script>

<a id="link1" href="#">Link 1</a>
<button id="btn1" onblur="(function(e){trapOn=true; document.getElementById('btn2').focus();})(event)">
	Button 1
</button>
<p>Press the M-key to Exit</p>
<button
	id="btn2"
	class="target"
	onkeydown="(function(e){ if (e.keyCode === 77){trapOn=false;document.getElementById('link2').focus();}})(event)"
	onblur="(function(e){ if(trapOn){document.getElementById('btn1').focus();}})(event)"
>
	Button 2
</button>
<a id="link2" href="#">Link 2</a>

Passed Example 6

Keyboard trap with "help" link that once clicked exposes the instructions.

<script>
	var trapOn = false

	function showHelpText() {
		document.getElementById('helptext').innerHTML = '<p>Press the M-key to Exit</p>'
	}
</script>

<div onkeydown="(function(e){ if (e.keyCode === 77){trapOn=false;document.getElementById('link2').focus();}})(event)">
	<a id="link1" href="#">Link 1</a>
	<button id="btn1" onblur="(function(e){trapOn=true; document.getElementById('helpLink').focus();})(event)">
		Button 1
	</button>
	<a id="helpLink" href="#" onclick="showHelpText()">How to go the next element</a>
	<div id="helptext"></div>
	<button id="btn2" class="target" onblur="(function(e){ if(trapOn){document.getElementById('btn1').focus();}})(event)">
		Button 2
	</button>
</div>
<a id="link2" href="#">Link 2</a>

Failed

Failed Example 1

Keyboard trap one element.

<a href="#">Link 1</a>
<button class="target" onblur="setTimeout(() => this.focus(), 10)">
	Button1
</button>

Failed Example 2

Keyboard trap group.

<button class="target" onblur="setTimeout(() => this.nextSibling.focus(), 10)">
	Button1
</button>
<button class="target" onblur="setTimeout(() => this.previousSibling.focus(), 10)">
	Button2
</button>

Failed Example 3

A focusable element inbetween to keyboard traps.

<button onblur="setTimeout(() => this.focus(), 10)">Button 1</button>
<button class="target">Button 2</button>
<button onblur="setTimeout(() => this.focus(), 10)">Button 3</button>

Failed Example 4

Keyboard trap with no instructions.

<script>
	var trapOn = false
</script>

<a id="link1" href="#">Link 1</a>
<button id="btn1" onblur="(function(e){trapOn=true; document.getElementById('btn2').focus();})(event)">
	Button 1
</button>
<button
	id="btn2"
	class="target"
	onkeydown="(function(e){ if (e.keyCode === 77){trapOn=false;document.getElementById('link2').focus();}})(event)"
	onblur="(function(e){ if(trapOn){document.getElementById('btn1').focus();}})(event)"
>
	Button 2
</button>
<a id="link2" href="#">Link 2</a>

Failed Example 5

Keyboard trap with instructions that doesn't give advise on the method for proceeding.

<script>
	var trapOn = false
</script>

<p>Go to the next element</p>
<a id="link1" href="#">Link 1</a>
<button id="btn1" onblur="(function(e){trapOn=true; document.getElementById('btn2').focus();})(event)">
	Button 1
</button>
<button
	id="btn2"
	class="target"
	onkeydown="(function(e){ if (e.keyCode === 77){trapOn=false;document.getElementById('link2').focus();}})(event)"
	onblur="(function(e){ if(trapOn){document.getElementById('btn1').focus();}})(event)"
>
	Button 2
</button>
<a id="link2" href="#">Link 2</a>

Failed Example 6

Keyboard trap with help text, where the method advised doesn't work.

<script>
	var trapOn = false
</script>

<a id="link1" href="#">Link 1</a>
<button id="btn1" onblur="(function(e){trapOn=true; document.getElementById('btn2').focus();})(event)">
	Button 1
</button>
<p>Press the M-key to Exit</p>
<button id="btn2" class="target" onblur="(function(e){ if(trapOn){document.getElementById('btn1').focus();}})(event)">
	Button 2
</button>
<a id="link2" href="#">Link 2</a>

Inapplicable

Inapplicable Example 1

No focusable element.

<h1>Page 1</h1>

Inapplicable Example 2

Disabled element.

<button type="button" disabled>Click Me!</button>

Inapplicable Example 3

Hidden element using display:none.

<button type="button" style="display:none;">Click Me!</button>

Inapplicable Example 4

Hidden element using visibility:hidden.

<a href="#" style="visibility:hidden;">Link 1</a> <button class="target" style="visibility:hidden;">Button1</button>

Glossary

Outcome

key: outcome

A conclusion that comes from evaluating an ACT Rule on a test subject or one of its constituent test target. An outcome can be one of the three following types:

  • Inapplicable: No part of the test subject matches the applicability
  • Passed: A test target meets all expectations
  • Failed: A test target does not meet all expectations

Note: A rule has one passed or failed outcome for every test target. When there are no test targets the rule has one inapplicable outcome. This means that each test subject will have one or more outcomes.

Note: Implementers using the EARL10-Schema can express the outcome with the outcome property. In addition to passed, failed and inapplicable, EARL 1.0 also defined an incomplete outcome. While this cannot be the outcome of an ACT Rule when applied in its entirety, it often happens that rules are only partially evaluated. For example, when applicability was automated, but the expectations have to be evaluated manually. Such "interim" results can be expressed with the incomplete outcome.


Changelog

Jul 19, 2019chore: run prettier (#688)
Jul 2, 2019Composite rules: Fix broken links in expectations (#627)
May 29, 2019chore: add missing contributors (#572)
May 18, 2019chore: Validating rules frontmatter on CI (#551)
May 18, 2019chore: Update site for accessibility and usability (#552)
May 9, 2019Chore: Adapt site to ACT Rules CR format (#547)
May 8, 2019Template update: No keyboard Trap (#543)
May 2, 2019fix: testcase for keyboard trap rule
Apr 29, 2019chore: rename files and update associations (#489)
Apr 17, 2019chore: fix typo in rules
Apr 16, 2019chore: add unique id to all rules (#478)
Apr 15, 2019chore: WCAG ACT RULES CG Website Update (#437)
Jan 14, 2019fix: composite rules have a listing of atomic rules
Oct 24, 2018Keyboard trap - Editorial changes (#318)
Oct 24, 2018Update SC2-1-2-no-keyboard-trap.md
Oct 9, 2018Update SC2-1-2-no-keyboard-trap.md
Oct 9, 2018Update SC2-1-2-no-keyboard-trap.md
Oct 5, 2018Added authors
Oct 5, 2018SC2-1-2-no-keyboard-trap
Sep 21, 2018Update SC2-1-2-no-keyboard-trap-non-standard-navigation.md
Aug 30, 2018Chore: Update test cases format and descriptions (#230)
Aug 8, 2018Rule: SC2-1-2-no-keyboard-trap-standard-navigation and SC2-1-2-no-keyboard-trap-non-standard-navigation (#171)
Jun 13, 2018Minor format changes
Jun 13, 2018Updated after review from Wilco and jkodu
Jun 13, 2018Update SC2-1-2-no-keyboard-trap-non-standard-navigation.md
May 24, 2018Updated testcases
May 24, 2018Create SC2-1-2-no-keyboard-trap-non-standard-navigation.md
May 24, 2018Rename SC2-1-2-no-keyboard-trap-standard-navigation to SC2-1-2-no-keyboard-trap-standard-navigation.md
May 24, 2018Rename SC2-1-2-no-keyboard-trap-r1.md to SC2-1-2-no-keyboard-trap-standard-navigation
May 24, 2018Update SC2-1-2-no-keyboard-trap-r1.md
Apr 5, 2018added rule SC2-1-2-no-keyboard-trap-r1

Useful Links


Implementations

Tool NameCreated ByReport

Acknowledgements