Saturday, August 16, 2014

The Anchor Button: Bad for Accessibility, Bad for Usability

<a href="#">I'm a button, click me</a> — this is the anchor button. Designers and developers have been creating buttons interchangeably with the <div>, <span>, and <a> elements instead of button and input. Who cares—on the surface things look great, right? Well, the easy answer is, wrong—incorrectly using HTML elements is a bad thing, and usually creates additional work to then add the expected default behaviors of the correct elements.

I'll first explain what the spec says about these elements and then I'll explain why following it is important and easy—the HTML 5 specification is actually not that difficult to understand, especially regarding these elements.

The DIV and SPAN

You've probably seen HTML markup that looks like a sea of <div> elements. Here's what the spec says about the <div>:
…The <div> element has no special meaning at all…authors are strongly encouraged to view the <div> element as an element of last resort…use of more appropriate elements…leads to better accessibility for readers and easier maintainability for authors.
The <span> element should be treated with similar consideration:
The <span> element doesn't mean anything on its own…

The Anchor

It's not uncommon to see anchors used like this <a href="#">I'm a button, click me<a/> with some corresponding javascript that will get triggered when the link is clicked. According to the specification, the <a> element should be used as follows:
If the <a> element has no href attribute, then the element represents a placeholder...if [it] has an href attribute, then it represents a hyperlink...[hyperlinks] are links to other resources...

Bad Semantics is Bad for Accessibility and Usability

Buttons and anchors have expected behaviors and states. When you use the wrong elements, these will not be present unless additional work is done to add them.
tab order
<div> and <span> elements are NOT by default in the tab order; button and input are. <a> elements without an href attribute are also NOT in the tab order. Elements typically not in the tab order can be added by setting the tabindex attribute to 0 on that element.
hover and focus states
<div> and <span> elements do NOT by default have a hover and focus state (note: some browsers do provide a default focus state for all elements); button and input do. You can add these states via CSS using :focus and :hover.
click and keypress
Unlike button and input elements, <div> and <span> do NOT by default trigger the associated click event on keypress of both the ENTER and SPACE keys. Additional work will also be required for an <a> element to trigger the click event on keypress of the SPACE key.
assistive technologies
Buttons—or anything else–marked up with a <div> or <span> appear only as plain text to assistive technologies. Also, while <a> elements are treated uniquely, it's common to identify all links on a page using assistive technologies to more easily navigate throughout a site. Therefore, it might be strange having those intended to be used as a button to be mixed up with the other actual links. Any element intended to be a button not marked up using button or input can have the ARIA role attribute set to button—keep in mind, though, all the behaviors/states above still need to be implemented.
Check out this Pen on CodePen to further understand the behaviors/states above. I've also created the a11yButton jQuery plugin that will add the behaviors above to non-button elements.

If it Looks Like a Duck and Quacks Like a Duck...

The simplest rule of thumb is to just use the right HTML elements for the content. Realistically, this is not possible 100% of the time—just remember, when using the wrong elements keep in mind there are behaviors and states that may be expected that will need to be accounted for.