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.

Thursday, June 12, 2014

Test-Driven Development Has You Covered

Most of us have probably been left to deal with software that at some time in history was loved by all. The business praised the developers on the team for building it so quickly, and the team felt pretty awesome—they were rock stars. Now we need enhancements, bug fixes, and better performance. Unfortunately, no one from the original team is around, and other developers are scared to touch it, because there are no tests, the architecture and design are overly complex, and understanding where to start seems impossible. What was thought to be a great success is now considered an epic fail. Software development isn't just about building something that works, it's also about building something that can be supported and maintained by everyone.

I'm very fortunate to work on a team that understands the importance and embraces things like pair programming and test-driven development (TDD). These are things, however, that you need to re-learn occasionally to make yourself and your team stronger. TDD is not new—in fact it's about 15 years old. Don't fear, practicing it doesn't make you a dinosaur. It's a technique that drives simplicity in your software and creates a safe environment for you and the rest of your development team.

What TDD Isn't

Sometimes TDD is misunderstood. It's not Test-first development, which suggests that all tests are written before the actual implementation. TDD doesn't mean writing tests after the implementation code has been written. TDD does not mean writing a test for every method of every class.

What TDD Is

TDD is a technique and a tool used to develop software by following the strategy of red, green, refactor—write a failing test against a public API that supports a small portion of business functionality, write just enough code to pass the test as fast as possible, and then refactor the implementation to ensure standards in design and quality are met and to remove any unnecessary code that doesn't support the business need (i.e. no anticipatory design...when you do this, you're spending your company's money or your customer's money on something they don't want).

TDD and Continuous Integration

There are many ways an application can be tested—all of which should be automated in a Continuous Integration (CI) environment. Could all of your functionality be tested using full system integration tests or automated web testing? Sure, as long as you don't mind waiting several hours to find out you broke something.

The goal of CI is to inform developers as soon as possible when bugs have been introduced to the application. TDD creates small, isolated unit tests that are intended to run in a very small amount of time. You still need system integration tests and automated web tests, but they should mainly be put in place to verify everything has been configured and/or wired up correctly—there should be little to no overlap across the different layers of automated tests.

100% Code Coverage...Are You Sure?

There are many tools to choose from that will help you determine how well your code is covered by your tests. Unfortunately, many of them won't tell you the quality of your tests. I'll demonstrate how TDD code coverage is different from non-TDD code coverage.

The code being tested is the AwesomenessCalc function shown in the Awesomeness Calc fiddle, which will tell you how awesome you are. I test-drove this code in the TDD Jasmine spec runner. I'm using Blanket.js to display the coverage in the spec as I'm developing. As you can see all tests are passing and the code is 100% covered.

Now let's pretend to write the non-TDD Jasmine spec runner after all the implementation code has been developed. All tests are passing and it also appears that the implementation is 100% covered. However, it's not fully covered—lines are getting executed by the spec runner, but the actual expected behavior is not being tested. You can also play with this non-TDD fiddle to see for yourself.

Nobody's Perfect

To understand and appreciate TDD in greater detail, I highly recommend watching Ian Cooper's talk "TDD, where did it all go wrong". It's a great reminder that you'll probably never get this 100% right, and how important it is to occasionally listen/watch something like this and reflect on how you currently do things.

Tuesday, May 27, 2014

One of Many Reasons WAI-ARIA Is Awesome...More Semantics

Accessible Rich Internet Applications (WAI-ARIA) is now a W3C recommendation, so it's important web developers start to understand what it is and how to use it. Also, there's something awesome about WAI-ARIA. Not only does it benefit people using your site, it benefits you as a developer—it provides you with an arsenal of semantic attributes you can target in your CSS and javascript.

WAI-ARIA in a Nutshell

Assistive technologies rely on and take advantage of HTML built using semantic elements appropriate for the content, like nav, header, main, button, ul, and dl—they provide people dependent on assistive technologies the best possible experience. However, even the best markup can't always adequately describe the content and/or its state on a web page. WAI-ARIA allows you to add more meaning to existing HTML markup with roles and their supporting states and properties—there are over 100 combined, including:
  • tree
  • banner
  • group
  • aria-live
  • aria-expanded

Your HTML Markup Just Got More Meaningful

Consider the HTML markup for a tree made of nested lists and toggle controls. The markup would look something like this (if you already know something about ARIA, pretend you don't):

<ul class="tree">
  <li class="tree-item parent collapsed">
    <ul class="sub-tree">
      item 1
      <li class="tree-item">item 1 child 1</li>
      <li class="tree-item">item 1 child 2</li>
      <li class="tree-item">item 1 child 3</li>
    </ul>
  </li>
  <li class="tree-item">item 2</li>
</ul>

There's really nothing wrong with the HTML above. Using ul and li elements instead of a bunch of div elements is great, because ul and li elements should be used to build a list of items. Also, the class names are meaningful. However, classes like tree, tree-item, and collapsed don't follow a spec and won't be consistently used from site to site where tree controls have been implemented—WAI-ARIA can help solve this problem. WAI-ARIA allows you to develop markup that looks like this:

<ul role="tree">
  <li role="treeitem" aria-expanded="false" aria-level="1">
    <ul role="group">
      item 1
      <li role="treeitem" aria-level="2">item 1 child 1</li>
      <li role="treeitem" aria-level="2">item 1 child 2</li>
      <li role="treeitem" aria-level="2">item 1 child 3</li>
    </ul>
  </li>
  <li role="treeitem" aria-level="1">item 2</li>
</ul>

Most of the Classes Are Gone—What About My CSS?

You don't need classes to style your markup. Target your HTML elements, and target the WAI-ARIA roles, states and properties using the attribute selector. For example, you could style the markup above as follows (from my LESS sheet):

ul[role="tree"] {
  list-style-type: none;
  &:focus {
    outline:1px dotted #0000ff;
  }
  li {
    list-style-type: none;
    &[aria-selected="true"] {
      color:#0000ff;
    }
    &[aria-expanded="false"] > ul {
      display:none;
    }
    &[aria-expanded="true"] > ul {
      display:block;
    }
  }
}

See It In Action

Too see WAI-ARIA in action check out the a11yTree jQuery plugin. I built it, because I wanted to learn more, and didn't quite like the other available tree plugins. HTML semantics with WAI-ARIA is important to ensuring the best online experience for everyone. Finally, if you're a craftsman you should take pride in this stuff just as much as everything else you do—HTML is code, too.

Saturday, February 8, 2014

Usability First

Mobile-friendly and accessible are 2 ways that many companies, product owners, and developers would love to describe the sites they build and contribute to. Usually, this is achieved by some form of remediation project, or 2 big epic stories in the backlog near the end of the list of priorities. To be fair, having the remediation project is sometimes a necessary evil; especially, if the site is at least 4 years old—the internet has changed a lot. For new projects, however, having an epic in the backlog for mobile strategy or accessibility is really an indicator of a growing problem the remediation project should also be trying to solve—a site that has some major usability problems.

What Usable Means

I recently read a post titled F*** You by Brad Frost. While I don't agree with everything Brad has to say in the post, it's a great read to remind all of us contributors to the web that not everyone is using an iPhone or the latest version of Chrome on a Mac to view our sites. Ultimately, you're most likely part of a business trying to make money so it's important you know your users and the technologies they're using—you can't make everything perfect for all variations of browsers, operating systems, and other technologies. However, if things like accessibility and mobile experience aren't even the smallest part of everything you do, you're building something that for some users is not usable.

Slice Things Horizontally

An old friend that's a very talented tattoo artist reached out through her network asking if anyone could help update her list of appointments on her web site built using Virb. The template she was using was simply listing all of her appointments in a 2 column list. Her goal was to make things a lot easier for her clients to look up their appointments, which are commonly made far in advance. She wanted a calendar view, which I agreed was a good idea, except that I didn't think a calendar view would be really usable on smaller mobile devices. I also wanted to consider users with disabilities.

So, rather than focusing on the mobile experience, or picking apart every aspect of a calendar with an accessibility lense, or simply trying to make the best damn looking calendar a tattoo artist could ask for—these are all vertical slices by the way—I decided on the amount of effort I'd put into updating the UI, determined the required features, and sliced up the work horizontally. For example, the current interation:
contains a calendar view
nothing fancy here; just your normal calendar arranged by year and month with days of the week headings
is usable on mobile devices
on any device smaller than an iPad, the calendar view switches to a date book view with only dates containing appointments—no frameworks, just simple media queries
addresses some accessibility concerns
the calendar uses a good heading structure, color contrast ratio is verified, aria-hidden used on days with no appointments, and each date read by screen readers contains the month, day of the week, and day of the month
Future iterations can be used to enhance the design, focus on specific mobile devices, or improve the navigation throughout the calendar to improve the experience for all users, including those with disabilities.

Check It Out!

You can see a snapshot version of the calendar at http://theaccessibleweb.com/examples/appts/index.html. I'd love questions, comments, and especially criticism.

There are a couple things about the demo I'd like to note based on some great questions and feedback from Dennis Lembree of Web Axe. The calendar is dependent on javascript being enabled—Virb heavily uses javascript templating; additionally, it was desired to keep the data entry process unchanged. Therefore, the calendar works by reading the DOM, building a new javascript object for the appointments, and rewriting the DOM. Based on the the feedback, I made sure that if javascript is disabled, the old DOM is visible along with a message to let users know the page is better viewed with javascript enabled.