Accessibility
The goal of having accessibility standards is to assist web authors in creating webpages that are accessible to all people, regardless of disability. One of the biggest upsides to an accessible website is that it provides a better user experience for everyone, not just for people with disabilities.
Nationwide strives to meet Web Content Accessibility Guidelines (WCAG) 2.2 AA standards and Section 508. Developers and testers should follow a three-step process on each webpage to ensure accessibility is addressed.
Step 1: Automated testing
Permalink to "Step 1: Automated testing"Developers and testers must run automated tools, such as aXe, which is an extension / add-on that can be used in Chrome and Firefox. Automated tools help identify the errors that can be easily identified and fixed.
Step 2: Keyboard testing
Permalink to "Step 2: Keyboard testing"Once the errors identified by the automation testing have been fixed, it's important to manually test them using the keyboard. Keyboard-only testing ensures that:
- All functionality works using only the keyboard (instead of the mouse)
- The focus is known at all times
- The focus moves left to right and top to bottom
Any functions that can't be performed using only the keyboard must be fixed. Some examples include opening / closing help text by clicking an icon, navigating through menus and sub-menus in navigation, and expanding and collapsing content.
The focus can be tested by pressing the Tab key. The focus should move to the next interactive element (link, input, button or any content with tabindex="0"). If the focus is lost at any time or does not move to the expected location, there could be several reasons, including:
- Links with
tabindex="-1" - Links missing href
- Mobile menus hidden offscreen that are still in the DOM
- Links that are created using
<span>or<div>rather than<a> - Buttons that are created using
<span>or<div>
Step 3: Screen reader testing
Permalink to "Step 3: Screen reader testing"There are several screen readers available:
- JAWS (licensed product, about $1,000 per license)
- NVDA (free; Windows OS only)
- Narrator (Windows OS; access by pressing the windows logo key + Ctrl + Enter)
- VoiceOver (Mac OS and iOS devices)
- TalkBack (Android devices)
When testing accessibility on a desktop (Windows or Mac), always use the keyboard instead of the mouse. This approach helps you understand how users with diverse needs navigate the site. Additionally, utilizing screen reader keyboard shortcuts provides insight into the challenges faced by those who rely on assistive technologies.
Learn more about the most common screen reader and browser combinations in WebAIM.
Semantic HTML for Accessibility
Permalink to "Semantic HTML for Accessibility"Use semantic HTML to make our content more accessible to users with assistive technologies such as screen readers. These technologies rely on the semantic meaning of HTML tags to convey the structure and meaning of content.
HTML provides several semantic tags for structuring web content. Here are some of the most commonly used semantic tags for structure:
<header>: Defining the header of a section or document. Typically contains branding, navigation menus, and other introductory content.<nav>: Defining a container for navigation links.<main>: Defining the main content of a document. There should be only one<main>element per page.<article>: Defining a self-contained section of content that could be distributed or reused independently.<section>: Defining a generic section of content that could be grouped thematically.<aside>: Defining content that is tangentially related to the main content, such as a sidebar or callout box.<footer>: Defining the footer of a section or document. Typically contains copyright information, contact details, and other closing content.
Source: https://www.semrush.com/blog/semantic-html5-guide/
Basic guidelines
Permalink to "Basic guidelines"All Bolt components have gone through accessibility testing, but please keep the following in mind and be sure to check the accessibility tab of each component's documentation for any additional steps necessary to implement the component in an accessible way.
- When it looks like a button, it is highly encouraged to use the native elements,
<button>, when you can. It is possible to use other elements such as<a>or<div>with therole="button"is added, however JavaScript need to be added to replicate the button functionality, such asonclick="event.preventDefault();". Bolt-button Link
<bolt-button href="http://www.nationwide.com" type="solid">Bolt-button Link</bolt-button>-
a href + role button
<a href="http://www.nationwide.com" role="button" onclick="event.preventDefault();">a href + role button</a> - If the button contains an
<img>element:- Decorative or redundant
<img>(those that have a visible text label) should have empty alt (alt="") on them. - Informative
<img>(those that are the only element in the button) should have an alt attribute value that describes the purpose of outcome of the button.
- Decorative or redundant
- If the button contains an icon:
- Decorative or redundant icons (those that have a visible text label) should have
aria-hidden="true"on them to ensure screen readers don't try to read the font icon or text embedded in an<svg>. - Informative icons (those that are the only element in the button) should place the
aria-labelattribute on the<button>or button equivalent element that describes the purpose or outcome of the button action.
- Decorative or redundant icons (those that have a visible text label) should have
- For example :
- The focus must be visible. Never set a link's
focustooutline: none - For a consistent look and feel, it's often useful for the
focusandhoverstyles to be the same or similar - Avoid "click here." The link should be as descriptive as possible (example: September 2019 Financial Report).
- A group of links, such as in headers, side navigation, footer, etc., should be marked up as a list - even when arranged horizontally.
<button>are used for accordions.- Accordion button text most often should also be marked with heading markup, e.g.
<h3> - Each
<button>hasaria-expandedattribute on it that is toggled between true and false.aria-expanded="true": content shownaria-expanded="false": content hidden
- Tables with one header and simple data are fairly accessible. Always use the simplest table configuration possible.
- Use
<th>as a header cells. Add following scope attributes when tables getting more complex:- Use
<th scope="row">for header rows. - Use
<th scope="col">for header columns.
- Use
- WAI Tables Tutorial can be found in w3.org tables tutorials, with the caveat that tables utilizing the headers/id method will not be accessible on Mac or iOS devices.
- Recommended to add
<caption>element before the table content as a headline for your table contents.
- Add
role="dialog"andaria-modal="true"attributes. - Add
aria-labelledby=""attribute and associated with the dialog headerid="", for example:<div id="dialog_entry_form" role="dialog" aria-labelledby="dialog_entry_form_label" aria-modal="true"> <h2 id="dialog_entry_form_label" class="dialog_label">Add your address</h2> </div> - When modal open, focus need to stay within modal box and prevent tabbing outside the modal.
- When modal closed by button/link or escape (
ESC) key, returns focus to the triggger/element that opened it. - Initial focus is set on the first focusable element, such as heading title, form input element, ok/close button. However when there are multiple dialogs/contents inside modal box, such as as verification result, form submission confirmation, etc, focus and accessible descriptions will be set based on the content of each dialog. This needs to be paid attention to :
- If the new dialog/content is similar with a confirmation page, where most users will simply dismiss the modal as soon as they have read the message :
- Set the initial focus on the
OK/Closebutton which is the last focusable element. - To help screen reader users understand the content, add
aria-labelledbyandaria-describedbyin the new dialog content to facilitate message announcement, for example :
<div id="dialog_confirmation" role="dialog" aria-labelledby="dialog_confirmation_label" aria-describedby="dialog_confirmation_desc" aria-modal="true"> <h2 id="dialog_confirmation_label" class="dialog_label">Thank you</h2> <div id="dialog_confirmation_desc" class="dialog_desc"> Your address has been updated. </div> <button id="dialog_confirmation_close_btn" onclick="closeButton()">OK</button> </div> - Set the initial focus on the
- If the new dialog/content is a form page, where it allows a user to enter data, set the initial focus on the first input focusable element.
- If the new dialog/content is similar with a confirmation page, where most users will simply dismiss the modal as soon as they have read the message :
- Heading tags should be in order, which means
<h1>is followed by an<h2>, an<h2>is followed by a<h2>or<h3>and so on. It is ok to skip heading levels when going up in order (ex.<h4>to<h2>). - The beginning of the main content should start with
<h1>. - Most web pages should have only one
<h1>. <h1>and<h2>give a user an overview of a page and how its content is structured.<h3>to<h6>give a quick understanding of the details in each section.- Please keep heading tags consistent to avoid confusion for screen reader users.
- Do not style text to give the visual appearance of headings.
- Please make sure to use the correct markup.
<ol>markup to group ordered list<ul>markup to group unordered list<dl>markup to group definitions list
- All list item
<li>elements are wrapped inside of<ul>or<ol>parent elements. - All list items
<dt>and/or<dd>elements are wrapped inside<dl>parent elements.
- If an element with
[role="alert"]remains in the DOM, DO NOT modify visibility via CSS without removing the[role]attribute.- When it becomes visible, a screen reader will announce a
[role="alert"]element as if it were just added to the DOM, which can be confusing to assistive technology (AT) users. - If the element is not applicable but needs to remain in the DOM, it's better to dynamically remove the
[role]attribute from the element so that screen readers no longer announce it. Afterward, it's safe to change visibility via CSS.
- When it becomes visible, a screen reader will announce a
- Placeholder text is not a replacement for
<label>. Usually it displayed with lower color contrast than content text color around and also it disappears from form fields when users start entering text, therefore placeholder can cause some difficulties for some users to complete the task. - Make required fields obvious by using an indicator, such as a border color change, asterisk or description text. If an asterisk is used, a note at the top of the form such as "required fields are marked with an *" is recommended.
-
Any form element with error validation should have
[aria-describedby]for screen reader users.-
If the error message has an
[id="first-name-error"], the input should have[aria-describedby="first-name-error"]. -
Only show
[aria-describedby]when errors occur.
-
If the error message has an
-
Trigger mid-form validation logic on events that occur while the relevant field is still focused/in context (e.g.,
inputorchangeevents).-
Avoid triggering validation on every
inputevent. Instead, apply a debounce so that logic triggers after a short delay, after the most recent event.
-
Avoid triggering validation on every
-
DO NOT trigger mid-form validation logic on
blurevents.-
This is especially true if using
[aria-live="polite"]to display mid-form validation errors (before form submission).- When the current/focused element changes, screen readers may announce the current element before announcing new error messages in the live region. If the current element is a form field, this can confuse the user, because the error message may sound relevant to the current field, but it is intended for the previous field.
-
Testing found that VoiceOver on macOS will announce the current element before announcing any
[aria-live="polite"]updates.
-
This is especially true if using
- Always include a
<label>with each element. Checkboxes/radio buttons without label tags are inaccessible to screen readers. Screen readers can't figure out which label belongs to which checkbox/radio button based on positioning alone. - Use
<fieldset>to surround the entire grouping of checkboxes/radio buttons. The<legend>provides a description for the grouping. - Some assistive technology reads the
<legend>text for each element in a<fieldset>, so it should be brief and descriptive. This helps someone using assistive technology to understand the question they are answering with the group of checkboxes/radio buttons. - Checking a checkbox or selecting a radio button must never create a change of context, such as moving the users focus to another location on the page or another page or window or change content above the checkbox or radio button.
- Make sure to use
<fieldset>and<legend>for grouped checkboxes/radio buttons.- For example :
<fieldset> <legend>Please select</legend> <div> <input type="radio" name="option" id="option_a" value="a"> <label for="option_a">Option A</label> </div> <div> <input type="radio" name="option" id="option_b" value="b"> <label for="option_b">Option B</label> </div> </fieldset>
- Add
role="search"on parent element of search component. For example:<form role="search"> <bolt-textfield iconalt="Submit Search" iconname="search" label="Search" optionaltext="hide"></bolt-textfield> </form>
- The
for=""attribute of the<label>must exactly match theid=""of the form element. It must be unique on each element.
- Per WCAG 2.2 § 1.4.3 Contrast (Minimum) -- Level AA
- Normal text requires a minimum contrast ratio of 4.5:1
- Large text requires a minimum contrast ratio of 3:1
- Exceptions to WCAG 2.2:
- Text in a disabled button does not need to meet the minimum contrast ratio.
- Text in a logo has no minimum contrast requirement.
- To use text over background images, make sure to add a solid background behind the text or a dark overlay to the background image.
- Avoid using only color to communicate information. For a link, use bold or underline to indicate a link instead of using color alone.
- Some users have difficulty reading text if there is too little contrast between foreground and background. To meet Level AA, text must have a contrast ratio of at least 4.5:1 (or 3:1 for large text).
- Bold text: 14pt / 19px / 1.2em / 120%
- Regular font weight: 18pt / 24px / 1.5em / 150%
- WCAG 2.2 also requires images that convey information to meet a minimum contrast of 3:1.
- For more information, refer to the following resources:
- Every
<img>you add to your site needs to have an alt attribute. - When the image being used as :
- Informational, set the
alt="descriptive alternative"for that image. - Decorative, set
alt="", which conveys to assistive technology users that the image isn't necessary for understanding the page. - Background with CSS, set
role="img"andaria-label="image description"on an empty<span>or<div>, not any HTML markup that contains with any content, otherwiseroleandaria-labelmight get ignored.- For example :
<div> <span class="bg-image" role="img" aria-label="image description">Content</span> </div>
- Informational, set the
- Be as descriptive as possible; avoid using generic strings like "photo," "image" or "icon" as alt values.
- Make sure your video player is accessible and includes control elements to pause, stop and play your media.
- If a video player is inside an
<iframe>or<frame>, ensure the elements contain a non-empty title attribute. - Do not auto-play your media.
- Captions are necessary for accessibility and usability.
- Videos are required to have an audio description track when there is information conveyed visually that is not also conveyed in the audio.
- Transcripts are also recommended for a video with audio description, or when an audio description is not required, because they are accessible to people who are deaf and blind. They can also be a benefit to SEO.
- SVGs, which are used for icons, logos and other images, can be resized without compromising visual quality.
- When using an
<svg>that is intended to be recognized by a screen reader:- Add
role="img"andaria-labelledby="titleidvalue"to the SVG element, where the value of aria-labelledby is the same as the ID value of the<title>element within the<svg>. - Update the
<title>element with an appropriate description. Informational images should have a text alternative that describes the information conveyed visually by the image, while the text alternative for functional images should convey the action or destination of the image.
- Add
- When an
<svg>is used for decoration, to "hide" it from a screen reader:- Remove the role="img" and aria-labelledby="" attributes and the
<title>element. - Add role="presentation" or role="none" or aria-hidden="true" to the
<svg>.
- Remove the role="img" and aria-labelledby="" attributes and the
- Couple things needs to be paid attention on the trigger button/link :
- Focus should remain on it.
- Needs to add
aria-label=""to describes the purpose the contextual help button/link. - Needs to add
aria-expandedattribute on it that is toggled between true and false.aria-expanded="true": contextual help content shown.aria-expanded="false": contextual help content hidden.
- Toggle
visibility:visible/hiddenon contextual help content div CSS. - To move/set the screen reader focus to its content, add
tabindex="0"on the content wrapper element.
- Wrap the breadcrumbs links inside a
<nav>element or addrole="navigation"into the markup, so screen reader user able to know that there is a pagination navigation when scanning the page with a screen reader. - If fixing content where adding a
<nav>element is not practical, usingrole="navigation"is a good approach. - Add
aria-label="breadcrumbs"into the<nav>element or the markup withrole="navigation". - Add
aria-current="page"to the last link that points to the current page. - If a list of navigation links is marked as a list,
role="navigation"cannot go on the<ul>as that will erase the<ul>semantics and the<li>s will no longer have a<ul>.
- Wrap the pagination links inside a
<nav>element or addrole="navigation"into the markup, so screen reader user able to know that there is a pagination navigation when scanning the page with a screen reader. - If fixing content where adding a
<nav>element is not practical, usingrole="navigation"is a good approach. - Add
aria-label="pagination"into the<nav>element or the markup withrole="navigation". - Labeling the links by adding a aria-label on each pagination link
aria-label="Go to Page 1" - Code example:
<nav role="navigation" aria-label="pagination navigation"> ... <a href="/page-1" aria-label="Go to Page 1">1</a> ... <a href="/page-2" aria-label="Go to Page 2">2</a> ... <a href="/page-3" aria-label="Current Page, Page 3">3</a> ... </nav>