Front-end Development Phase

This section highlights accessibility considerations specific to front-end development. Code snippets have been added where relevant as examples.

Warning - Try not to get lost in the weeds. There may be more than one “right” way to do something. The goal is to make things incrementally better for the widest audience possible.

Component Demos

Perceivable

1.1 Non-text content

Important Images have a text alternative.

Information conveyed by an image should have a text alternative in case the image cannot be viewed. This is a basic concept, but there is an art to writing appropriately descriptive text to replace an image.

How to do it

Informative Images: Contains information that is not represented elsewhere. Note this typically isn't a literal description of the image.

<p>
  <img src="images/dog.jpg" alt="Dog with a bell attached to its collar.">
  Off-duty guide dogs often wear a bell. Its ring helps the blind owner keep track of the dog’s location.
</p>
          

Decorative Images: Images used as spacers, icons, purely decorative, and CAPTCHA images, or other situations where the alt attribute would be redundant with the other page content.

<p>
  <img src="sleepingdog.jpg" alt="" role="presentation">
  Let sleeping dogs lie: Let sleeping dogs lie is a proverb that means “don’t initiate trouble. If something that could be troublesome is quiet, then leave it alone”.
</p>

Functional Images: Images used as buttons or other interactive elements.

<a href="javascript:print()">
  <img src="print.png" alt="Print this page">
</a>

Addtional situations where alt attributes should be used:

  • Images of text.
  • Complex images (such as charts).
  • Groups of images that collectively have one meaning (such as star ratings).
  • Image maps. Because everyone uses these.

More detailed information is available in this tutorial for writing text alternatives

Critical Form inputs have properly associated text labels.

Labeled form fields mean a screen reader can explain what information should be entered.

How to do it

Whenever possible, this should be accomplished with a for attribute on the label that references the id of the associated field.

<label for="firstname">First name:</label>
<input type="text" name="firstname" id="firstname">
How should radio buttons or groups of checkboxes be labeled?

For consistency, labels should be associated with a for attribute like other form elements. Wrapping the label around the input works, but is less flexible. Note that a fieldset and legend should be used on all but the simplest sets of checkboxes or radio buttons.

More details about forms can be found in the forms and error handling section.

Frames are titled.

Descriptive, unique titles allow screen readers to explain what is in any frame on a page, making navigation easier.

How to do it
<iframe src="banner-ad.html" id="testiframe"
  name="testiframe" title="Advertisement">
  <a href="banner-ad.html">Advertisement</a>
</iframe>

1.3 Page structure

More information can be found in this page structure tutorial.

Important Headings, lists, and special text are used appropriately.

Headings and other tags provide information about what content is available, and which piece is most important on the page. This information allows people using assistive technologies to “see” an overview of the page and jump quickly to the section that is relevant to them.

How to do it

Make sure the page title is an <h1>, and that it is the only <h1> on the page.

Use heading tags to create an outline structure for the main content on the page.

<h1>Outline structure based on heading tags...</h1>
  <h2>...</h2>
    <h3>...</h3>
      <h4>...</h4>
      <h4>...</h4>
      <h4>...</h4>
  <h2>...</h2>
    <h3>...</h3>
      <h4>...</h4>
    <h3>...</h3>
    <h3>...</h3>
How do you adjust heading styles for presentation without breaking heading order?

One cleanish way to switch the visual style of a heading without breaking the heading order is to use a heading class that mirrors the styles on the native headings. Something like h2, .h2 { styles... } This can allow sidebars and other blocks to look right while avoiding too much extra CSS.

Use lists or special text to help describe the type of content being presented. For example: <strong> semantically means important, while <b> just means visually bold, not necessarily more important.

Caution: Tables in a rich text editor

TinyMCE and CKEditor are the most common editors in the CMS we use. Both are limited in what kind of table an editor can reasonably create.

Here are some features and limitations to be aware of.
Feature TinyMCE 4 CKEditor 4
Wrap table in div with a class No No
Add a class on the table tag Yes* No
Can add headings Yes Yes
Can add a caption Yes Yes
Can add thead or tfooter No No
Can set percent-based widths Yes Yes
Can force percent-based widths Yes* No
Can suppress styling options Yes* No
Prestyled tables Yes** No

* This requires adding the tables plugin to TinyMCE.

** TinyMCE has the concept of a template that drops in predefined HTML. This could offer a way to start editors off with a good base table.

Important The page order is clear and makes sense.

Maintaining a logical order of elements on the page, both visually and in the source code avoids confusion for all users.

How to do it

Separate navigation, content, and other supplemental sections of the page into distinct blocks. HTML5 tags and ARIA roles can help communicate this structure.

<body>
  <header role="banner">
    <div id="logo">HTML5 logo</div>
    <nav role="navigation">...</nav>
    <div role="search">...</div>
  </header>
  <main role="main">
    <h1>HTML5 page structure</h1>
    <p>The purpose of the HTML5 tags is to provide a logical structure and outline for the content of a page.</p>

    <article>
      <h2>Blog post title</h2>
      <p>...</p>
    </article>

    <article>
      <h2>Another blog post title</h2>
      <p>...</p>
    </article>
  </main>

  <aside role="complementary">
    <div class="box">
      <h2>Sidebar</h2>
      <p>...</p>
    </div>

    <div class="box">
      <h2>Sidebar</h2>
      <p>...</p>
    </div>
  </aside>

  <aside role="complementary">
    <ul>
      <li>Footer links...</li>
    </ul>

    <div class="box">
      <h2>Signup Form</h2>
      <form>...</form>
    </div>
  </aside>

  <footer role="contentinfo">
    <address>Contact Info...</address>
    <p>©Copyright 2018</p>
  </footer>
  </body>

Currently ARIA landmark roles are still used in addition to HTML5 tags for better support across browsers and other assistive technologies. This can be seen in the previous code example.

Avoid shuffling the visual order of elements unnecessarily with CSS. This is especially important for navigational links and form elements. Flexbox and CSS grid can easily shuffle elements visually leaving the focus order chaotic.

Pro Tip - Try turning off all CSS and see if the flow of the page still makes sense.

What is the difference between an <article> and a <section>?

A <section> is part of a larger “thing”, and is likely to have siblings that are similar in concept, like chapters in a book. An <article> is a complete thing on its own. So, this could be something like a blog post or a poem. Both sections and articles can be nested inside eachother.

More information can be found on the W3C about HTML5 sectioning. Another set of examples can be found in this random blog post.

Use more than one sense for instructions.

Avoid relying solely on things like shape, sound, position and size to identify page elements in instructions.

How to do it

Don’t use sound alerts in general. But if you do, also include a text indicator of what is going on.

Make instructions detailed but clear, considering that elements may move depending on the device, or may be interacted with without visual feedback.

Tables often rely on visual relationships between cells to make the data understandable. To maintain these relationships for assistive technologies, the correct markup must be in place. More information can be found in this tables tutorial.

Accessible Tables

Tables make sense for tablular content. But giant tables of data simply don't fit on small screens. How can you provide a usable experience for people, and maintain accessibility?

Start with a well structured table. Define column and row headings. Use a caption to identify the table, similar to a title or heading. For more complicated table structures, use the scope attribute to associate column and row headings with the correct data. Solid markup is your friend. Then get fancy as needed. Some responsive layout options include:

  • Horizontal scrolling: Bootstrap includes the option to wrap a table in a div with the "responsive-table" class. This keeps a wide table from breaking the page layout, giving a horizontal scrollbar on the table instead.
  • Table stacking: Reassign CSS display properties to table elements to create a single column view of the data on small screens without duplicate markup, or complicated javascript. Here is a table stacking demo.
  • Reordering content with JS: A more invasive approach would be to toggle columns, or shuffle content as desired with a javascript solution like tablesaw.js. This approach is the most powerful, but really only works with a controlled table structure. No site editor can touch this.
Table Alternatives

Don't use tables for layout purposes. We aren't savages here. If you're tempted, here are some alternative ways to put things beside eachother:

  • Description lists: If you have a two column table. You may really want a description list (formerly a definition list).
  • Just float it: You want an image next to some text? Just float it, and use a class to make the spacing look nice.
  • Bootstrap columns: If you're using Bootstrap already, this is an easy win for simple content, and reflows responsively.
  • Flexbox: For structural layout of things in a row, flexbox can mimic many of a table's attributes, but also can reflow responvively.
  • CSS Grid: For two-dimensional alignment of elements on the screen, CSS Grid is what you want. Just don't go wild shuffling the order of elements, or risk confusing people who rely on the tab order.

1.4 Text size, links, and color contrast

Critical Audio that plays automatically has controls to play, pause, mute, or adjust volume.

How to do it

The best practice is to avoid audio that plays automatically in the first place. But if you have to, give users control of that audio, so it isn’t competing with screen readers, or generally annoying everyone.

Note that short audio alerts less than three seconds are excluded from this rule.

Level AA Page is readable and functional when the text size is doubled.

Accommodate mild vision impairments by allowing text to scale without breaking the layout or functionality of the site.

How to do it

Using em-based font sizes across the site allows for easy proportional resizing of the text without having to adjust many separate elements individually. In Bootstrap the base font size is set on the body. If you set the headings, paragraph, etc. tags to use ems, you can control the font size proportionally site-wide by adjusting the pixel value on the body element itself.

In general, a fluid responsive layout responds well to variable text size with little adaptation.

Areas to watch

  • Elements with limited heights or widths. Horizontal navigation, image carousels with overlayed text may need some extra attention to expand gracefully.
  • Similarly. Elements with heights set in javascript may need a manual reset when scaled up.
  • Very large heading text may become so large that individual words don't fit within the width of the page and end up clipped. In these cases, these headings may be able to be excluded from scaling beyond a reasonable point.
  • Fixed position elements can fill the available space and obscure the page content when scaled up, so use with caution.

Note - This guideline has been previously interpreted to mean that font resizing controls need to be provided in addition to the browser’s built in scaling capabilities. That doesn’t seem to be necessary according to this interpretation of the text-sizing requirement, unless scaling the page with the browser does result in clipped text or unusable controls.

Level AA Real text is used vs. relying on images of text.

How to do it

Text should be text, so it works like text. Some exceptions are logos, or text in an image that is decorative rather than meant to be read. But generally speaking, just use real text.

Critical Color Contrast

Color contrast description.

A background color should always be set, even when it won't show under normal circumstances. Missing and disabled background images reveal the background color. Many times this is a failing variable in accessibility tests.

Fail Example
Typical View

Example Heading

Images Disabled

Example Heading

Pass Example
Typical View

Example Heading

Images Disabled

Example Heading

Gradient Background

Background gradients can cause accessibility tests to fail when the contrast is actually compliant. To pass, add a solid background color to the end of the gradient in the CSS.

Code Example
background: linear-gradient(to right, rgba(35,118,200,1) 0%,rgba(2,84,160,1) 100%) rgb(35,118,200);

Operable

2.1 Keyboard access

Critical All page functionality is available using the keyboard.

How to do it

Navigation with tab, , return, and spacebar are the most common methods of browsing with a keyboard. Although this is fairly basic, testing can uncover unexpected glitches or highlight pain points with the controls, page structure, etc.

Note - Different browsers focus on a different set of elements by default. Typically this can be adjusted in the browser preferences under the accessibility options. Safari is the exception. It uses a keyboard setting on the OS level (System Preferences > Keyboard > Shortcuts > Set full keyboard access to “All controls”). The hotkey to toggle this setting is control+F7.

How do you make off-canvas menus keyboard accessible?

Off-canvas functionality is just a specialized type of expandable content so, the accessibility adaptations are the same:

  • Use a button to toggle the menu open and closed (rather than an a) since it is a control not a link.
  • Adjust the aria-expanded state on the button to keep it in sync with the state of the menu. This enables the screen reader to announce whether the menu is expanded or collapsed.
  • Make sure the menu is actually hidden from screen readers and the tab index when closed to avoid confusion.
  • Keep the content of the off-canvas directly after the button that expands it in the source order. This makes it easily findable. If this isn’t possible, you will have to manage the page focus manually in javascript using $(this).focus(); and adding tabindex='-1' on the off-canvas content wrapper.

Here is a javascript snippet showing how to manage the aria-expanded state:

var    toggleBtn = '.btn-off-canvas-toggle',
       navWrap = '.l-header__nav';

// toggle off-canvas
$(toggleBtn).on('click', function() {

    if ($(toggleBtn).attr('aria-expanded') == 'false') { // off-canvas is collapsed

        // syncing aria-expanded attribute on the menu button
        $(toggleBtn).attr('aria-expanded', 'true');
        // reveal hidden nav
        $(navWrap).css('display', 'block');

    }
    else { // off-canvas is expanded

        // syncing aria-expanded attribute on the menu button
        $(toggleBtn).attr('aria-expanded', 'false');
        // hide nav from screen readers and tab focus
        $(navWrap).css('display', 'none');

    }
});

Note - The variables above line up with Marshall’s off-canvas plugin, but this (obviously) doesn’t show the complete off-canvas code.

Here are some more examples of using aria-expanded on the W3C. Note that collapse.js in Bootstrap uses aria-expanded out of the box.

An accessible date-picker.

Selecting a date or date range is a deceptively complicated interaction that isn't directly covered by a native input. So how do we do it well?

Just use an input field

At the most basic, an input field that asks for a date would work. However, even with format validation, this puts a lot of responsibility on the user to get the format right.

Adding a type="date" to an input field gives you an automatic date picker in Chrome, Firefox, Edge, and iOS. No luck in Safari or IE. Mileage will vary in terms of accessibility. This could be a nice native approach if all the browsers get a solidly implimented solution.

Date format: mm/dd/yyyy.
Multi-step date input

You can split the date into individual month/day/year select boxes or input fields. This turns the date selection into a series of simple interactions rather than one more complicated one. It is a durable, but somewhat limited and tedious approach.

Enter a Date
Use a date picker plugin

Creating a solid date-picker that is touch friendly, uses aria tags, and is keyboard accessible is complicated. Most available plugins were not built with these things in mind. The Pick a Date plugin is one option that provides a good starting point.

Page-specified shortcut keys do not conflict with existing browser and screen reader shortcuts.

How to do it

Avoid shortcut keys. They can seem like a good idea, but in practice make a site function differently than the rest of the web. If you need shortcut keys the underlying design may just need some tuning to be more traditionally accessible.

An exception to this is online tools that function more like an app. If the user will be returning often to do specific tasks beyond standard input functionality, hotkeys may make sense. In that case, avoid common keys for keyboard navigation including the tab, , return, and spacebar keys.

Critical Keyboard focus is never locked or trapped at one page element.

The goal is to make sure there isn’t a dead end on the page that stops someone from using the site with a keyboard.

How to do it

Watch for drop down menus, popups, frames, or third-party widgets that accept focus but don’t provide a way out.

Keyboard trap exception

The possible exception to the keyboard trap rule is when this behavior is beneficial to control the scope of the page navigation. For example:

  • Off-canvas navigation that loops focus within the menu when open.
  • Within an open modal that overlays the primary content.

In these cases it would be more confusing to have the page focus shift off these content areas while they are open. Provided there is a clear method for closing these items (and freeing the page focus), this should be in compliance.

How do you ensure all content is accessible if javascript is disabled?

One way is to detect if javascript is available, and tune your site styles to make sure all content is visible and not too jumbled without JS help.

Start with a no-js class on the html tag.

<html lang="en" class="no-js">

Use a script to replace the class. If the script does NOT run, javascript is assumed unavailable.

<script>
   document.documentElement.className =
   document.documentElement.className.replace('no-js','js');
</script>

The no-js class lets you create a fallback state where you can target things like tabs and sliders that may need adjustment. You can also hide controls for functionality that depends on JS to work. Best practice is to display hidden content by default, and visually it hide after the page loads, so hopefully there isn’t too much to do.

.no-js {
    //examples of tuning display of elements to make more sense if there is no JS
    .search-link, .text-resizer, .nav-tabs {
        display: none;
    }
    .collapse {
        display: inherit;
    }
    .tab-content > .tab-pane {
        display: inherit;
    }
}

2.2 Moving content and time limits

Carousels that rotate automatically have controls to stop and start the action.

This guideline gives people control over the speed they read content as well as a way to reduce the visual distractions on the page.

Note - This also applies to other moving, blinking, scrolling, or automatically updating content.

How to do it

Provide an option to control the frequency of an automatically updated section of content. With a carousel, this means adding a play/pause button as well as the next and previous buttons or other navigation.

Exceptions - This doesn’t apply to things that don’t start automatically. So a carousel that doesn’t rotate on it’s own is fine. Any movement that lasts less than five seconds is exempt as well.

How do you make a carousel accessible?

Carousels are a usability problem for any user. Making one decently accessible is that much more of a challenge.

DEMO - Here is an enhanced Owl Carousel.

More information can be found in this carousels tutorial.

2.3 Don’t cause seizures

No page content flashes more than 3 times per second.

It’s all fun and games until you’re the guy that made someone’s brain fritz out. Don’t be that guy.

How to do it

Avoid adding animated GIFs or other video or animation elements that flicker too fast, especially anything red. For more information, review this definition of general flash and red flash thresholds.

Include a skip navigation link.

Provide a link to skip past repetitive content such as the main navigation to ease tab browsing of the site.

How to do it

This technique can be used carefully in a variety of cases, but jumping past the header and right to the main content of the page is the most common use.

Add an anchor link as the first element within the body that points to the main content for the page. Note that a tabindex of -1 has been put on the <main>. This helps the focus shift properly on all browsers.

<body>
<a href="#maincontent" class="skip-link">Skip to main content</a>
...
<main id="maincontent" tabindex="-1">
   <h1>Heading</h1>
   <p>This is the first paragraph</p>

Style this link to be visible only on tab focus. This lets it be useful for tab navigation and screen readers without interfering with standard browsing.

.skip-link {
  position: absolute;
  top: -100px;
  left: 0px;
  &:focus {
    top: 0px;
    color: #fff;
    text-decoration: none;
    display: block;
    padding: 15px 25px;
    background-color: $blendgreen;
    z-index: 1;
    }
  }

More details on skip links

Important The focus order of the page is logical.

Navigation links, form elements and any other focusable pieces are in a reasonable order. Both visual and tab navigation order should make sense.

How to do it

Start with a logical source order for the HTML, and avoid unnecessary shuffling of elements with CSS.

If things NEED to change order at different responsive break points, it is probably better to actually move elements in the DOM with JS, or possibly show/hide duplicate markup rather than just visually move them with CSS. This will necessarily be a judgement call based on the specific situation.

Pro tip - Stepping through pages with tab navigation occasionally while building templates is a quick way to find unexpected order issues.

Link text and context indicates the purpose of the links.

Make links clear and easy to understand so the user knows what to expect before they click.

How to do it

Here are some ways a link can pass this test:

  • The text within the link is descriptive enough on it’s own.
  • The purpose of the link is clear from the surrounding content.
  • If the link is an image, the alt text of the image makes the link purpose clear.

Note - To avoid confusion, only links with the same destination should have the same description.

Level AA Multiple ways are available to find pages.

How to do it

Make sure a site has more than one of these ways to navigate.

  • Clear and consistent main navigation.
  • Site search on every page.
  • An HTML sitemap page (which links to every page on your website) with a link to it after the “Skip to Content” link.
  • A related links section.

Exceptions - Confirmation pages, and sites with very few pages may not need multiple navigation paths.

Should menus open on hover or click?

Menus have to open on click/tap. That doesn’t mean there can be no hover state, but touch devices typically can’t access hover states, and keyboard access isn’t good if a menu relies on hovering. There are three common approaches:

  1. This basic menu opens when the label is clicked.
    Fig 1. Labeled menu button
    Labeled menu button - A nav item that has a dropdown menu does not also link to a page. It just opens the menu when clicked. Following this structure means there are no landing pages that “contain” other pages. It is more of a folders and pages setup. This is how the Bootstrap navbar works.
  2. A split link menu gives more flexibility.
    Fig 2. Link + menu button
    Link + menu button - In this approach, text links all point to pages and there are separate buttons used to open the associated menu. You get landing pages, but it can be a challenge to make the extra buttons clearly clickable. This is how Flexnav and the Marshall’s MLN menus work.
  3. A mega menu contains more options.
    Fig 3. Button + mega menu
    Button + mega menu - This approach is kind of a hybrid of the first two. Menu items with dropdowns open the menu like Fig. 1, but in this case the menu itself is more elaborate than a simple list of links. There can be landing pages with nested pages as well as other featured content.

This is an architectural choice that should be considered in the strategy phase. Make sure what is being built lines up with the intended site map. More information about menus can be found in the keyboard access section.

Important Level AA It is visually apparent which element has keyboard focus.

Mostly this means the focus outline hasn’t been squashed in CSS, and hidden elements don’t get focus. However, it is possible to enhance the look of the focus style to be more obvious and look nice with the overall site design.

How to do it

Outside of any element specific styles, the outline style is typically used to highlight focus. It is similar to a border, but doesn’t take up any space, so the layout doesn’t change or break if it is turned on and off. If you’re making changes, the focus style should be considered for every element type that can recieve focus.

.btn,
.btn.active,
.btn.active.focus,
.btn.focus,
.btn:active,
.btn:active.focus,
.form-control,
.navbar-toggle,
a,
input[type="checkbox"],
input[type="file"],
input[type="radio"] {
   &:focus {
      outline: 5px auto #98b658;
      outline-offset: -2px;
   }
}
Things to watch for
  • The outline typically falls outside the bounding box of an element. This means elements that are tight against eachother, such as a grid of photos, can obscure the focus outline. Using a negative outline-offset, or adjusting the z-index of an element on focus can overcome this problem.
  • Visually hidden items that are still tab accessible allow the page focus to get hidden too. Watch for this in carousels, menus, and expandable content.
Why do some elements get a focus ring on mouse click and others don’t?

Apparently some browsers distinguish between tab focus and focus from a mouse click. They use this to suppress the focus styles on some elements when clicked on. Buttons are commonly handled this way, but it isn’t consistent. Plus, a link with a role of button is probably handled differently in the same browser!

So, while it would be nice to have better control over when the focus ring displays, there currently isn’t a good way to normalize things across browsers. This can be fixed by hiding the content from the accessibility tree as well as visually. display:none will work, but there may be more subtle ways to manage this depending on the situation.

Understandable

3.1 Languages

The language of the page is identified using the HTML lang attribute.

How to do it
<html lang="en">

3.2 Predictable site behavior

When an element received focus it doesn’t change the page in confusing ways.

How to do it
  • Don’t open a pop-up window, submit a form, jump keyboard focus to another element, etc. when an element receives focus.
  • Exceptions - Opening a drop down menu or adjusting a link style on focus aren’t really a change of context, so they don’t cause a problem here.

Interacting with a control doesn’t change the page in unexpected ways without informing the user ahead of time.

Mostly this means only submit form data when a user chooses to click a submit button. But there is some nuance.

How to do it
  • Forms must not auto-submit when all fields are filled.
  • Focus must not automatically jump to the next field in a form once a field is complete.
  • Using a control (like selecting yes or no, or choosing an item in a select box) must not automatically perform the action.
How do you open a search box or other collapsible element and help a user find that content?

Use an aria-label to alert the user of a focus jump or other atypical behavior before clicking.

Demo - Here is a focus shift demo.

More information about expandable content can be found in the keyboard access section in the off-canvas example.

When does it make sense to programmatically change the page focus?

Some scenarios that may require manual page focus management:

  • Skip to content or back to top links.
  • Jump to the search field when a collapsible search form is expanded.
  • Opening or closing a dialog/modal.
  • Off-canvas navigation if the menu trigger is separated from the menu in the DOM.

Level AA Repeated functionality is consistently identified. (For example, site search is labeled the same.)

How to do it
  • Icons are used consistently (for example, ‘Print page’ or Twitter link).
  • Elements with the same function are labelled and named consistently.
  • Elements with the same function have a consistent text alternative.

3.3 Forms and error handling

More information can be found in this forms tutorial.

Required form elements or specific format requirements are noted in the element’s label.

Identify any mistakes that you can detect and explanation what is wrong close to the form element.

How to do it
  • If a form requires input in a certain format, show and describe the required format.
  • If a mandatory field is empty, highlight the field and explain what’s required.
  • Build forms to be forgiving, accepting variations on the formats you prefer.
  • Don’t ask for too much information, just what you need.
  • Be specific. Use clear, concise instruction and form field labels.
  • Highlight mistakes in forms with colors AND symbols.
  • Don’t clear a form if a user makes a mistake. Save the information and allow the user to edit their error and continue.
  • Provide contact details on all pages (the footer is fine).

Demo - Here is a set of form examples based on our current best practices.

Important Sufficient labels, cues, and instructions for required interactive elements are provided.

Clear labels and instructions mean users will know what to do.

How to do it
  • Where a field needs a specific format, give an example (For example, for a ‘date’ field in a form you might use ‘Enter the date as dd/mm/yyyy’)
  • Mark required fields with an icon and explain what the icon means before the form.
  • Keep labels simple. (ex: ‘First name’, ‘Email’ , ‘Your message’)
  • Keep instructions simple. (ex: ‘Required fields are in red and have a * symbol’, ‘Fill in this form and click ‘Submit’ to get in touch’)
How do you display a dynamic alert in an accessible way?

aria-live - off, polite, assertive

Using role="alert" is equivalent to using aria-live="assertive". This means it interrupts spoken content with a verbal message when added to the page.

Details needed.

Level AA If an input error is detected (via client-side or server-side validation), provide suggestions for fixing the input.

This guideline adds the requirement to make suggestions on how to fix form errors.

How to do it
  • If the error is in the format of the input, the suggestion shows the correct format (for example, ‘The date must be in the form DD/MM/YYYY’).
  • If the error is because the input needed to be from a limited list of values, provide these values and explain them.
  • If a user makes an error, provide a list of links that the user can follow to jump back to correct their input.

Robust

4.1 Maximize compatibility

HTML/XHTML validates without significant parsing errors.

Make sure your markup is good. Following specs makes a site more likely to work as expected with any assistive technology.

How to do it

Major errors and broken code are the problem here. Minor warnings generated by an automated validator don't necessarily mean failure.

There are lots of these, but here is the W3C validator.

Validity - Chrome extension to validate HTML on the current page.

Follow the HTML/XHTML specifications and using forms, form labels, frame titles, etc. appropriately to facilitate accessibility.

Standard HTML controls already pass this requirement when used according to spec. If you write your own interface components, the roles, states, properties, and values need to be managed accessibly.

How to do it

Start with a clean HTML structure that is as semantically descriptive as reasonably possible. Think of ARIA as enhancements to clarify intent, extend compatibility, or overcome non-standard HTML.

WAI-ARIA attributes will need careful use to bring custom controls up to speed. The updated AIRA spec has lots of details.