When a website or application has good accessibility (or a11y for short), that means that the site is built with all users in mind. Making your site accessible ensures that users with varying levels of ability are able to properly navigate your page with screen readers, keyboard, and various other accessible tools. There are a few simple changes you can implement in order to drastically improve the accessibility of any web application or site:

  1. Use native elements
  2. Ensure proper labeling
  3. Focus styles
  4. Skip to content
  5. Implementing keyboard navigation

With our 7.0 release of WebViewer, we have implemented a large number of accessibility improvements to ensure that people with a diverse range of abilities are able to easily navigate our user interface, including the five points above. Let’s look into each of these points to determine how to implement them in your own applications, and what benefits they have on accessibility.

linkUse native elements

The quickest and easiest way to ensure that your application will function in a predictable way is to use native elements such as button, a, and p. Simply using these will ensure that any users who are accessing your app using keyboard navigation will be able to focus and interact with the content. For example, by simply using a native button element the user is able to focus it using tab, and click it using the space or return key. That is much easier than manually adding listeners and tab indexes to your elements to make them function like buttons.

Sometimes, people avoid using native elements because it can be a pain to remove any default browser styling from them. The easy fix to that is either adding global styling to remove browser-specific styles. Our solution was to add a Sass mixin that could be easily added to any elements to remove the default button styles for a clean slate.

@mixin button-reset {
  // These are just to remove some of the
  // default browser styles on buttons.
  padding: 0;
  border: none;
  background-color: transparent;

  // This becomes `html:not([data-tabbing='true']) .your-class`
  // at the root level, ensuring that when the data-tabbing
  // attribute is not true there will be no button focus style.
  @at-root html:not([data-tabbing="true"]) #{&} {
    outline: none;
  }
}

linkEnsure proper labeling

Generally, screen readers can parse the content of an element such as a button or anchor by reading the text contained within it. This is great for buttons with text, but what about icon buttons? These generally contain nondescript SVGs or icons that screen readers are unable to get valuable information from. In cases like these it is important to add a description of the element to the aria-label attribute. The screen reader will read from the aria-label when that element is focused, and the user will be able to determine the purpose of the element.

If your application is internationalized, ensure that you are also translating the aria-label's, not just the text content of elements!

const translatedLabel = t("next_page");

<button aria-label={translatedLabel}>
  <Icon i="right_arrow" />
</button>;

linkFocus styles

Removing focus styles is one of the worst things you can do for accessibility. Developers have a tendency to go outline: none as soon as they begin styling a button. This is ok, as long as you make sure to implement some indication that an element is being focused. Many UI kits have implemented custom styles for their focused elements, but in a lot of cases that comes at the cost of having the focus rings appear whenever the element is clicked, even though the user is not navigating using their keyboard.

In the new UI we have found the sweet spot where focus styles only come in when the user is using keyboard navigation, and they stay hidden when the user is navigating using their mouse. This preserves the styling of the application until focus indicators are actually needed. This is enabled whenever the user presses the tab key or uses keyboard navigation within a menu component, and disabled whenever the user clicks.

Focus styles when using keyboard navigation

linkSkip to content

Implementing a skip to content box can help keyboard-navigating users skip to the sections they want without having to tab through the entire UI to get there. In practice, they remain hidden until the user begins tabbing, at which point it should be the first thing they encounter.

Skip to content selector

linkImplementing keyboard navigation

In an ideal world, if you have implemented everything with native elements, you should avoid the need for implementing custom keyboard navigation. However, there are specific cases where you may be required to do this. One example is trapping focus within a modal to prevent the user from tabbing outside of it. Another example is with menus.

When you tab to a menu it is focused normally.

Focused menu button

However, once you click it, instead of using tab the user will use the keyboard up and down keys to cycle through elements.

Open menu with first item focused

This mimics the functionality of native select elements. Implementing something like this is relatively easy, and can be achieved in a few steps:

  1. When the element opens:

    • Add a keydown listener to the document
    • Store a reference to the currently focused element (this will be the button that opened the menu)
    • Track all focusable elements within the bounds of the menu. (you can use a simple DOM string with querySelectorAll -- here’s an example of the string we use in the WebViewer React Toolkit)
  2. When the keydown listener is triggered:

    • If the key is up arrow, move the focus to the previous focusable element (if it’s already the first one, you can choose to ignore it, or cycle to the last element)
    • If the key is down arrow, move the focus to the next focusable element (same as up arrow, you can decide whether to cycle focus or just stop at the last element)
    • If tab or escape are pressed, close the menu and return focus to the reference you stored to the button that opened the menu. This will behave correctly with pressing tab, as the element will be focused prior to the default action (moving to the next item)

Once you have that all together, it looks something like this:

Keyboard focus within menu

linkResources

I have covered many of the high impact changes you can make to improve accessibility across your application. However, there are many tools and resources available to help ensure that your front end is set up for all users.

https://accessibilityinsights.io/ - A tool created by Microsoft to audit your front end for accessibility bugs and improvements

https://a11yproject.com/checklist/ - A web application accessibility checklist for ensuring your site meets the Web Content Accessibility Guidelines standard

https://www.pdftron.com/samples/web/samples/advanced/accessibility/ - To see it all in action, check out the WebViewer 7.0 accessibility demo