Making elements keyboard focusable and clickable

When you want to make an element on a web page clickable in order to trigger a JavaScript function, the best option is to use an element that has native support for keyboard interaction. In most cases a button (either <input type="button" /> or <button type="button"></button>) is the most appropriate element. It lets everybody trigger your function, whether they use a mouse or not.

Unfortunately, many (maybe even most) developers do not use the correct HTML elements for this. Instead they often use elements that have no native support for keyboard interaction, like span, div or li. A slightly better choice is the a element since it can receive keyboard focus as long as it has a non-empty href attribute (i.e. <a href="#">Click me</a>). But it isn’t really a link anymore since it acts like a button and doesn’t lead anywhere.

So why do so many developers choose the wrong element to trigger functionality? I think the main reason is styling. Once upon a time browsers did not let you change the way button elements look a whole lot, which forced developers to use elements that could be styled freely. It is many years and browser versions ago that this was necessary though (see some examples of Styled submit buttons from 2004). All browsers in widespread use today let you change the way buttons look.

Another reason is lack of knowledge. Many don’t know that you can style buttons these days, and many others don’t know that using elements without native keyboard support can easily cause serious accessibility problems.

What do I suggest then? There are two options:

  1. Use real buttons and style them so they look the way you need them to look.
  2. If you simply cannot or will not use real buttons, make sure your fake buttons can be focused and activated without using a mouse.

In both cases, to avoid confusing non-JS users, you should also use JavaScript to add interactive elements to the DOM unless they do something useful even if JavaScript is disabled.

Option 1 is easiest and most robust, so that’s what I recommend. But if you choose option 2, here’s what you need to do for your fake button to mimic a real button as best as it can:

If you use jQuery, inserting a span element that works like a button might look like this:

$('<span>', {
	'class': 'button', // So you can style it
	role: 'button', // Tell assistive technology it's a button
	tabindex: '0', // Make it keyboard focusable
	click: function() { // Make something happen when it is clicked
		alert('You clicked me!');
	},
	keydown: function(e) { // Trigger the click event from the keyboard
		var code = e.which;
		// 13 = Return, 32 = Space
		if ((code === 13) || (code === 32)) {
			$(this).click();
		}
	},
	html: 'Click me!'
}).appendTo($('#button-container'));

See the Making elements keyboard focusable and clickable demo page to compare the following four different approaches:

For mouse users all of these work. Click any of the button-looking elements and an alert will pop up. But if you use the keyboard to tab to each of the buttons, here’s what happens:

The bottom line is this: either use natively keyboard accessible elements (preferable) or make what you use instead mimic the appropriate native element as closely as possible.

Posted on February 12, 2013 in JavaScript, Accessibility