How to make pages keyboard accessible

Provide visual styling for keyboard focus

Make sure people can see where keyboard focus is. The easiest way to do this is to define the outline property in your CSS rules. The outline is the line that's drawn around elements, outside the border edge, to make the element stand out when they get keyboard focus. Some browsers do this nicely themselves (like Safari on OS X), but many do not.

Example

a:focus, input:focus, select:focus, textarea:focus, button:focus {
  outline-width: 2px;
  outline-style: solid;
  outline-color: #0AB4E2;
}

If you have special controls you've rolled yourself (e.g. using a <div> for a button), you'll need to add selectors to your style:

a:focus, input:focus, select:focus, textarea:focus, button:focus,
div.imageButton:focus, li.menuItem:focus {
  outline-width: 2px;
  outline-style: solid;
  outline-color: #0AB4E2;
}

Make sure controls can be reached

If you cannot reach a control using the Tab key only, it's likely the type of element: some HTML elements don't normally receive keyboard focus. This is common when <div> elements are used for buttons, tabs, etc. (with functionality added through scripting), but other elements might be culprits. Check the HTML for the control you can't reach.

You can fix this problem by setting the element's tabindex value to a non-negative number. Setting tabindex=0 will add the element to the tab order in it's natural position in the DOM.

Example

<div class="save-button" tabindex="0">Save</div>

If the HTML is being generated in JavaScript, you can use the Infusion Keyboard Accessibility Plugin to programmatically make elements tabbable:

Example

$(".menu-items").fluid("tabbable");

Often, you may have two adjacent links to the same target, for example a logo and a name, both linking to the organization's website. Obviously, you want both things to be clickable, but you don't really want both things to be in the keyboard tab order: If they are, then the keyboard user has to tab through two identical links.

In these cases, it's helpful to deliberately take one of the links out of the tab order. In this example, since the link around the name of the organization already contains text that would be useful to a screen reader user, it makes sense to remove the logo link from the tab order.

Example

<div class="idi-logo">
  <a href="http://inclusivedesign.ca" tabindex="-1">
    <img src="idi-logo.png"/>
   </a>
</div>
<div class="idi-name">
  <a href="http://inclusivedesign.ca">
    Inclusive Design Institute
  </a>
</div>

Make sure dialogs get focus

Dialogs are often implemented by a hidden <div> at the bottom of the page that is shown and positioned absolutely when the user activates something. It is important that when a dialog is displayed, keyboard focus is moved to the dialog by default. Most good dialog widgets will do this, but if they don't, or if you're rolling your own, do it programmatically yourself. Depending on the dialog, focus might go to the first input field, or to a Cancel or Ok button.

deleteButton.click(function () {
   areYouSureDialog.show();
   areYouSureDialog.cancelButton.focus();
});

Make sure dialogs can be dismissed

It can be very frustrating when you can't get rid of a dialog that's in your way. Most dialogs have a Close button somewhere. Make sure the button can be reached using the Tab key. It is also good practice to make sure that the Escape key will dismiss a dialog. This can be done in JavaScript:

// close the dialog on Escape key
theDialog.keydown(function(event) {
    if (!event.isDefaultPrevented() && event.keyCode && event.keyCode === $.ui.keyCode.ESCAPE) {
        theDialog.close(event);
        event.preventDefault();
    }
});

Make sure pop-ups pop up

If something pops up (or drops down) when the cursor hovers over it, it should also pop up (or drop down) when someone navigates to it using the cursor. Some things (like a tooltip) should pop up when the element receives keyboard focus; other things (like a menu) might not pop up until the user presses Enter or Space – but it should pop up if they do.

For small things like tooltips that you want to show automatically, bind the same action to focus that you do to hover:

var showTooltip = function () {
    tip.show();
};
var hideTooltip = function () {
    tip.hide();
};
control.hover(showTooltip, hideTooltip);
control.focus(showTooltip);
control.blur(hideTooltip);

For some things like menus, you might want the menu to display only when the user specifically triggers it. This should happen when the user presses the Space or Enter key. Infusion's Keyboard Accessibility Plugin can be used to easily make the menu button activatable using these keys:

// make all list items in the user menu activatable using the keyboard
$("li", userMenu).activatable();

See Also