Accessibility

Accessibility at Instrument is a cross-discipline effort that brings in expertise from development, strategy, design, and production. We hold our work to a high standard – it’s not enough just to innovate and to demonstrate technical skill, but whatever we make should be accessible and inclusive as well.

Accessibility as a Priority

Instrument’s work to promote accessibility involves alignment throughout the project lifecycle, from the initial SOW to ideation and execution. Our typical level of accessibility is WCAG 2.0 AA compliance and we have worked with clients to craft WCAG 2.0 AAA-compliant experiences, as their legal and strategic needs required.

Committing to accessibility also means internal education in the form of workshops and documentation, as well as empowering individuals to push for better accessibility on a day-to-day-basis. We ensure that accessibility is called out in SOWs and schedules, and we engage QA teams who will be able to evaluate our work for WCAG compliance.

Getting Started

The steps below are roughly in order from least to most effort; there’s a lot more to accessibility than what is mentioned here.

Consider these items both during development and before approving a pull request.

There are different levels of accessibility support. WCAG 2.0 provides documentation on how to meet these levels. We should always meet level AA criteria at a minimum. The various levels and their requirements are outlined in the How to Meet WCAG 2.0 document.

Important: Some of the tools mentioned below require sending the HTML and/or development url to a third party service. Consider what that means. Projects involving sensitive data should avoid using those in favor of local options.

Validate HTML

Remember when people wrote xHTML and people would claim their site’s validity with a badge? As HTML5 became the standard, a lot of validation habits died with xHTML as the validation is much looser. While browsers might be able to visually render a page with poor HTML structure, it’s not as easy for assistive technology. Unclosed tags and incorrect application of attributes can quickly become detrimental to accessibility.

There may be cases where validation errors are required to work around other issues. For example, an inline SVG within a button element can gain focus from tab or clicking. Tabbing through that page would result in both the button and svg gaining focus while only one should. This can be prevented by adding focusable="false" and tabindex="-1" to the svg element. However, those attributes are not currently valid on an svg element.

Validation is an easy task, especially for a static site. Here are a couple tools to get started:

  1. W3C Validator
  2. Grunt HTML5 Lint

In addition to documented, testable validation rules, also consider the semantic validation of a document. Make sure to use appropriate HTML elements for layout, content, hierarchy and interaction. Heading order is actually important (h1, h2, h3, etc) – check that the document outline makes sense: HTML5 Outliner Bookmarklet or HTML5 Outliner Chrome Extension. Use buttons for buttons, links for links, footers for footers, etc. NO <a href="#">, EVER.

Automated tests

We have an account with Tenon.io. While automated tests can’t catch everything they can highlight testable issues – things like invalid link references caused by href attributes whose value are just “#”, out of order header elements, abusing placeholder attributes instead of providing a proper label, etc.

Note sometimes tests can return false positives or there may be cases where need to ignore the testable case. For example, if there are offscreen headers describing lists of links before a proper h1 element, there will be a warning about it. However, in this case, it may make sense to have an h3 before any h1. It is correct to establish a header level for these cases and use the same level everywhere it applies. For example, all non-hierarchical list header elements in the site header and footer could be h3.

Accessibility browser plugins

There are a number of Chrome plugins to test various accessibility metrics. These are useful both for seeing testable issues and giving a different look into what the browser or an assistive device sees. For example, catch missing alt attributes or incorrect header order or get a look at the document outline or see all the present ARIA attributes.

  1. Accessibility Developer Tools
  2. WAVE

Keyboard navigation / focus states

An accessible site can be navigated entirely through keyboard usage. This is easy to test. Try tabbing through the page. It should be evident what element is focused at any given time and all actionable elements should be able to receive focus. This is a good test to make sure spans (which don’t naturally receive focus) weren’t bound with javascript to do some click action that should have been implemented with a button element (whose purpose is to trigger actions and can receive focus by default).

Consider interactions where it may be appropriate to jump a user to a different part of the page. For example, if clicking a “load more” button, once that content has filled in, often it is best to focus the first new item that was loaded rather than maintain focus on the button itself.

Ideally someone less familiar with the project would test this. It’s a lot easier to assume context when you built it and have an expectation of what should be happening. See how it works for someone that has no prior knowledge of it.

Focus styles

This is dangerous:

*, *:focus { outline: none; }

Make sure you can always tell what element has the focus state. This is where focus styles become important. The default focus styles are often removed for aesthetic preferences. It’s important to replace that style with a suitable alternative. Typically, using the same style for both hover and focus works well:

@mixin hover() {
  .hoverable &:hover,
  &:focus,
  &:active {
    @content;
  }
}

Keep in mind that a fully accessible focus state is indicated by more than just motion and any color-change-only style should meet required contrast ratios.

Managing Focus Styles gives a nice overview of options, links to additional articles and a technique for determining if mouse or keyboard caused the focus.

Keyboard traps

Beware of keyboard traps. Any component on the page that can be focused using the keyboard should also allow for unfocusing using the keyboard. There may be special cases where it is intended to temporarily trap a user (for example, to require input in a modal), but it should be made clear what is required to exit.

offscreen focus

It is desirable to not create duplicate content for visual users and assistive technology. Sometimes design requirements make that difficult. In that case, make sure the offscreen content obtains the keyboard focus through the tab key while at the same time adding a -focus class with appropriate styles to the visual element. Remove the visual version from the tab index using tabindex="-1" to avoid redundant tabbing.

Skip links are offscreen elements that allow quick navigation to specific parts of a page. Typically they should be the first item in the page tab index. When gain focus, CSS should display them on screen.

Typical targets for skip links include the main content area or navigation but may also include more specialized links such as an about section or cart button.

// Offscreen styles. Typically just use a generic
// .-off-screen modifier class on any elements that
// need this rather than repeating css.
%off-screen {
  clip: rect(1px, 1px, 1px, 1px);
  clip-path: inset(50%);
  height: 1px;
  margin: 0;
  overflow: hidden;
  padding: 0;
  position: absolute !important;
  width: 1px;
  white-space: nowrap;
}

// Use when you want an off-screen element to be
// visible when focused for accessibility.
%off-screen-focus {
  clip: auto;
  clip-path: auto;
  height: auto;
  overflow: auto;
  width: auto;
}

.skip {
  @extend %off-screen;

  &:focus {
    @extend %off-screen-focus;
    background: $bg-dark-grey;
    color: $type-light-on-dark;
    left: 50%;
    margin: 0 0 0 -100px;
    padding: 6px;
    text-align: center;
    top: 0;
    width: 200px;
    z-index: 10000;
  }
}

Not all HTML elements receive focus equally. To make sure a target element that doesn’t otherwise receive focus (for example, a div) can be focused, give the element tabindex="-1". A -1 value for the tabindex property is typically used to remove it from the tab index but also has the side effect of making an otherwise unfocusable element focusable.

Unless using javascript to detect mouse vs keyboard interaction, this may be an example of a case where applying outline: none; to the element is useful as visual users could be confused if clicking a content area caused outlines to show up as that is not typical behavior.

Offscreen text

Offscreen text is any text that is not needed in a visual context but is helpful for assistive technology. This is the most bulletproof offscreen CSS:

%off-screen {
  clip: rect(1px, 1px, 1px, 1px);
  clip-path: inset(50%);
  height: 1px;
  margin: 0;
  overflow: hidden;
  padding: 0;
  position: absolute !important;
  width: 1px;
  white-space: nowrap;
}

Source

Any element with the .-off-screen class will be “visible” to assistive devices without being displayed to visual users.

This can be applied to text used to give hints as to the context of elements within the page. A good example is offscreen headers. Typically any HTML list element should be preceded by a header indicating the contents of the list that follows. Most assistive technology can quickly jump between header elements in a page so the headers provide shortcuts through the content. It may also be applied to alternative text based versions of content.

Test Colors

A design should be tested for accessible color ratios both in the design phase and the development phase. There are tools for both cases.

  1. Easy Color Contrast Testing
  2. Chrome Color Contrast Analyzer
  3. Sketch Color Contrast Analyzer

Where state is indicated by color, make sure that color-blind users can discern the difference in the UI. Preferably by using words rather than color. See this for a particular egregious example of a poor UI for color-blind users.

Zoom

Partially-sighted users often need to zoom to read on desktop, laptop and mobile environments. Test that layouts don’t completely fail when the page is zoomed both as a whole using the browser’s zoom facility and with increasing just the text size. General text content will flow without issue. Check any elements that may have an absolute height, width or position set by CSS.

Don’t break zoom on mobile devices – avoid using initial-scale=1.0; maximum-scale=1.0; or user-scalable=no in the viewport meta tag.

Text alternatives

Provide text alternatives to all content. The simplest example of this is alt attributes on images (images that aren’t considered content should have an empty but present alt attribute: alt="").

Beyond alt attributes, images can have longer descriptions. Video and audio should have text scripts. Interactive elements should have text based alternatives that offer the same level of content as the visual counterpart.

Icons and icon fonts

Use inline SVGs/sprites for icons rather than icon fonts.

Icon fonts fall short for reasons of accessibility and support. Screen readers and alternative fonts (such as OpenDyslexic) often have trouble with icon fonts; Opera Mini users don’t have @font-face support and won’t see the icons at all.

Inline SVGs with descriptive text are a more robust icon solution re: accessibility and are scalable, flexible, and spritable.

Provide text-only information about the icon (e.g., for screen readers) via the title and desc attributes on the svg (see also: Text Alternatives).

If the icon is for visual purposes only (such as in a button) and you don’t want to provide a title or desc, hide the icon using aria-hidden="true" and use an offscreen label for the icon and/or button to provide additional context for screen readers:

<button class="drawer-open-button js-desktop-drawer-open">
    <span class="-off-screen">Show topic drawer</span>
    <span class="material-icon" arial-hidden="true">
        <svg class="desktop-drawer-open" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M15.41 7.41L14 6l-6 6 6 6 1.41-1.41L10.83 12z"/></svg>
    </span>
</button>

Recommended Reading:

Forms

All form elements should have an associated label, whether that label is visible or placed offscreen for screen reader use. placeholder is not a substitute for input labels.

If a form element is required, it should be labeled clearly as such. If a form is submitted and errors are found in validation, the error should be associated with the corresponding invalid field and aria-invalid="true" should be set on the field. See this article for more on accessible form validation.

Form elements should be placed in logical tab order in the markup so that if a user is tabbing from field to field, it makes sense. For example, a first name field and a last name field should not be separated by an email field. Relatedly, make sure all your form elements are focusable and navigable via keyboard controls.

Custom form controls can often lead to accessibility problems. As much as possible, use native elements for forms and style appropriately. div-style shims for select dropdowns are often quite quirky and not easily navigable via keyboard. If you must create completely custom functionality for your form elements, test thoroughly to ensure accessibility.

ARIA

ARIA stands for Accessible Rich Internet Applications. It is a set of HTML attribute designed to make content more accessible to assistive technology. It can be used to describe the state of a page, changes within the page, relationships between elements on the page and much more. It’s also easy to get wrong. Start with the basics and test to make sure any attributes are working as expected and not causing more harm than good.

Two common ARIA attributes are aria-role and aria-hidden. aria-role declares the role an element plays on a page. Its values include header, footer, navigation, etc. aria-hidden can be set to true to make an element invisible to assistive technology while still being available to visual users. This can be helpful when providing a text alternative to an interactive element on the page. Do not hide content or functionality from assistive technology if there is not an alternative available to it.

VoiceOver

OS X includes VoiceOver support. It can be enabled through System Preference > Accessibility or by pressing cmd + F5. While it’s an easy way to get a general idea of how a site performs, it isn’t as robust as others are (JAWS, NVDA). Additionally, screen readers require practice to use efficiently. Only using one to test a feature probably isn’t going to give a good picture of whether a site actually works well for someone who always navigates the internet with one.

A few basic commands:

  • cmd-F5: Turn VO on and off
  • ctrl-opt-right/left: Next/prev item
  • ctrl-opt-down/up: Enter/leave area
  • ctrl-opt-space: Click link
  • ctrl-opt-cmd-h: Next header element
  • ctrl-opt-a: Read all
  • ctrl-opt-h: Open VO help menu
  • ctrl-opt-cmd-right: Change voice preferences (person, rate, pitch, volume)

User testing

User testing with someone accustomed to using assistive technologies is the best way to understand shortcomings in a project. They can give more perspective to what they expect based on prior usage and what either works well or is confusing.

Test with keyboard-only users. Test with users that zoom their browser or zoom only their text size. Test with users that always navigate with a screen reader. Test with color blind users.