10 Steps to Building Web Applications With Accessibility (a11y)
A detailed guide to making your web accessible to all
Accessibility (a11y) is the practice of making web applications that are usable for people whose abilities are limited in some way, such as vision (using a screen reader) and mobility (using the keyboard only). In addition, the limitation could come from the device’s capability, such as mobile devices.
The followings are the rationales of accessibility:
- It provides equal access to everyone, including people with disabilities.
- It improves usability for a more intuitive user experience.
- It meets federal, state, and international laws to make electronic and web content accessible to people with disabilities. Violating these laws can result in loss of funds or contracts.
It takes time and effort to build up usability, and it would be important that usability is baked into the framework of web applications. In this article, we will provide ten steps on how to build web applications with accessibility.
- Step 1: Choose semantic HTML
- Step 2: Use built-in keyboard access
- Step 3: Avoid positive tabindex for setting navigation flow
- Step 4: Reach full keyboard access
- Step 5: Make focus and hover equal / Use
mouseoverover mouseenter/Use mouseout over mouseleave - Step 6: Ensure web pages are functional without CSS
- Step 7: Fill accessibility gap with WAI-ARIA
- Step 8: Offer text alternatives and more for media content
- Step 9: Make text size and color distinguishable
- Step 10: Pass audit tool tests
Step 1: Choose Semantic HTML
Semantic HTML introduces meaning to web pages rather than just presentation. Sometimes, it is called Plain Old Semantic HTML (POSH).
The following is the semantic definition of a heading:
<h1>This is heading text</div>Visually, it would look the same with the specified style:
<div style="font-size:32px;font-weight:600;">This is heading text</div>However, div is not a correct way to implement a heading. Although it looks the same on the desktop, it will be translated incorrectly by a screen reader.
Historically, there are two common pitfalls in web development:
- Emphasize a text using
<b>instead of<strong>. - Lay out elements using
<table>instead of CSS.
HTML5 provides us with all the semantic elements to write the markup in a meaningful way, such as <article>, <details>, <figure>, <nav>, <section>, and <summary>. Search Engine Optimization (SEO) gives more importance to the content inside these tags and makes the underlining web page more searchable.
It is recommended to use Semantic HTML, and it is also important that a web page’s HTML is semantically correct.
W3C has a website to validate the markup validity of web documents in HTML, XHTML, SMIL, MathML, etc. We can use it to make sure HTML syntaxes are used correctly.
Here is the result of validating https://www.amazon.com/:

Even a commercially successful website has room to improve.
Step 2: Use Built-In Keyboard Access
Keyboard access is essential to accessibility. A keyboard user typically uses the Tab, Shift Tab , or arrow keys to navigate through interactive elements on a web page, such as buttons, input fields, selections, links, etc. When an item gets focused, it can be activated or manipulated with a keyboard. An action can be performed by clicking the Enter or Spacebar key.
WebAIM provides keyboard testing rules for autocomplete, dialog, slider, menu bar, tab panel, tree menu, etc.
The following are the focusable rules:
<input>,<select>,<textarea>,<button>, and<object>are focusable if they are not disabled.- Anchors are focusable if they have an
hrefortabindexattribute. <area>is focusable if it is inside a named<map>, has anhrefattribute, or there is a visible image using<map>.- All other elements are focusable based solely on their
tabindexattribute and visibility.
Based on these rules, <button> is focusable. If you need a button, use <button>Run</button> or <input type=”button” value=”Run”>.
It is discouraged to use <div>Run</div> with CSS and tabindex. This div element may provide a similar style or behavior, but the built-in accessibility will likely be lost.
Using built-in keyboard access conforms with the rule of using semantic HTML. Since you do not need to implement additional plumbing, it is likely that semantic elements will end up with a smaller bundle size than non-semantic code.
Step 3: Avoid Positive Tabindex for Setting Navigation Flow
The navigation order in which interactive items receive keyboard focus is important. The default order should be logical and intuitive. The general flow is from left to right and from top to bottom. The navigation order should come from the document’s source order. Avoid positive tabindex for setting navigation flow.
tabindex is a global attribute that indicates that its element can be focused and can be part of navigation flow if the value is not negative.
tabindex="-1"(or any negative number) means that the element is not in navigation flow, but it can be focused with JavaScript or by clicking.tabindex="0"means that the element is in navigation flow. The order is after elements with positivetabindexvalues. Among elements withtabindex=“0”, the order is defined by a document's source order.tabindex="1"(or another positive number) means that the element is in navigation flow. The element with a smallertabindexvalue is ordered first.
Can you guess the following Tab order?
<div tabindex="0">Third</div>
<div tabindex="-1">Not Reachable</div>
<div tabindex="0">Fourth</div>
<div tabindex="2">Second</div>
<div tabindex="1">First</div>It is First, Second, Third, and Fourth.
What is the screen reader order?
It is Third, Not Reachable, Fourth, Second, and First.
Do you see the inconsistency?
It is a good practice to use a screen reader to test web pages during development.
MacBooks have excellent built-in accessibility. You can turn on VoiceOver for screen reading.

You can also use the ChromeVox Classic Extension, which is a screen reader on Chrome for visually impaired users.

Step 4: Reach Full Keyboard Access
The Web Content Accessibility Guidelines (WCAG 2) explain how to make web content more accessible to people with disabilities. It provides four categories of guidance:
“1. Perceivable: Information and user interface components must be presentable to users in ways they can perceive.
2. Operable: User interface components and navigation must be operable.
3. Understandable: Information and the operation of user interface must be understandable.
4. Robust: Content must be robust enough that it can be interpreted reliably by a wide variety of user agents, including assistive technologies.”
For each guideline, there are testable success criteria with three levels: A, AA, and AAA. The minimal level is A and the target level is AAA.
Keyboard access is all about operability. When implementing web pages, we should first use built-in keyboard access. If it is not available for a complex user interface, tabindex can be implemented to fill in the gap. The goal is to reach full keyboard access.
Step 5: Make Focus and Hover Equal / Use Mouseover Over Mouseenter / Use Mouseout Over Mouseleave
Focus indicates that the component is currently selected. In order to satisfy WCAG 2’s Perceivable and Operable rules, when the cursor moves around an application, the focused item should be visible. The visual indication should be large enough to cover the component area, and the bounding area should have sufficient color contrast and thickness.
Focus is true if the cursor is in that element and the element has the :focus pseudo-state. Hover is true when the mouse pointer is over an element and the element has the :focus pseudo-state.
Most of the time, focus and hover act in concert. It is possible for focus to be true while hover is false. If a user clicks a form element and moves the mouse away, focus is true and hover is false. If a user tabs to a form element, it also triggers a case where focus is true and hover is false.
Typically, a focused item has an outline bounding it. This outline can be hidden by applying CSS of outline:0 or outline:none, though it is against the guidance.
In addition, CSS can be used to make the focused item more visually prominent (contrast or thickness) or styled to match the whole website design.
When styling focused items, we can use the :focus pseudo-class. It is a good idea to double up focus and hover styles. Therefore, users get the same visual indication that a control is ready to perform an action, whether it is hovered by a mouse or focused by a keyboard.
The following is an example to show a red outline when elements are hovered or focused:



















