Keyboard Trap

A keyboard trap occurs when focus is moved into an interactive element or control with a keyboard but cannot move focus away using a keyboard alone.

The Problem

Users that rely on keyboard navigation get stuck in an interactive element, unable to navigate away.

The Solution

Take care when using JavaScript event listeners for blur and key[down|up|press] events paired with preventDefault. Be sure to constrain to only the events you need, ensure you've built in a way to escape.

Related Articles

Live Examples

Before illustrates the problem, After illustrates the solution. Click the header to see it larger in a modal.

before

after

Code Comparison

Code diff between the before and after examples above to show the changes necessary. To copy the final source click on the 'after' path link before the diff.

source

Comparing /examples/focus/keyboard-trap/before/index.html to /examples/focus/keyboard-trap/after/index.html

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Accessibility Solutions - Focus - Keyboard Trap</title>
<link rel="stylesheet" href="../../../presentation.css">
</head>
<body>
<main id="main" role="main">
<p>Contrived example that requires an action on keypress of the "Q" button in <a href="#" class="trapped">this link</a>. Velit ea optio est adipisci beatae alias porro voluptatibus culpa dicta veniam, esse quidem nihil odio voluptatem error tempora nostrum minima magni et.</p>
<p>Deleniti possimus <a href="#">corrupti mollitia</a> cupiditate totam facere molestias, sunt amet exercitationem inventore odio veritatis eaque doloribus esse tenetur officia, odit hic obcaecati harum nostrum blanditiis ratione, fuga in?</p>
</main>
<script src="keyboard-trap.js"></script>
</body>
</html>

javascript

Comparing /examples/focus/keyboard-trap/before/keyboard-trap.js to /examples/focus/keyboard-trap/after/keyboard-trap.js

(function() {
'use strict';

// Define values for keycodes
var VK_Q = 81;

var el = document.querySelector("a.trapped");

el.addEventListener('keydown', (e) => {
e.preventDefault();
var keyName = e.key;
var keyCode = e.keyCode;
if (keyCode === VK_Q) {

e.preventDefault();

console.log('keydown event - key: ' + keyName + ' code: ' + keyCode);
}
});

}());