eCommerce Accessibility A11y
A11y eCom UX Tutorial

eCommerce Accessibility A11y

Scott C. Krause | Monday, Dec 7, 2020

Website accessibility design and development can be both challenging and rewarding. However eCommerce properties by their very nature present an extreme set of challenges and rewards. Focusing on the positive; Improved accessibility can indeed lead to greater online sales. Building a better experience for a greater number of people cannot be bad for the bottom line. Unfortunately the negative side of that coin is that popular eCom sites are often targets of predatory troll litigation. For an eCom front-end developer accessibility has become an extreme sport with real consequences. We’ve had to redefine success, rethink our tool chain, and go back to HTML 101.

Accessibility is not so much a destination as it is a journey. It's a cyclical process of constant improvement and re-evaluation.

I have experience making large eCommerce sites accessible. I’ve authored a11y pattern guides, automated tests, and best practices that have helped disparate teams achieve WCAG / 508 success criteria. In this article I present tips and tools for achieving eCom accessibility nirvana.

In order for improvements to stand the test of time, there must be a company culture that supports accessibility and be willing to make it a requirement even when faced with competing priorities. For example, imagine explaining to an art director that the brand colors cannot be perceived by the color-blind. Imagine telling an SEO consultant that there are too many characters in an alt attribute. These can be awkward conversations if a11y is not prioritized within the organization.

Every tier of management must embrace the “engage everyone” mantra because it’s simply too easy to justify cutting corners. The website is not successful until it is accessible.

Large eCom sites are particularly challenging because they are always changing. Product information and imagery are managed within a CMS, therefore, there is always a risk of newly-added content being inaccessible. Ideally this situation would be addressed with a cyclical audit. That is a web crawler that captures a11y issues throughout the entire site. Similarly an a11y audit could run as part of automated unit testing upon software build or check in.

Finding a11y issues during development is preferred but keep in mind the developers will require more time to become proficient in this discipline and the project estimates should reflect that.

Color Contrast

Chrome Dev Tools
Pro ⚡ Tips

💡 If you do not see this dialog in Chrome dev tools try swapping the foreground and background colors.

Before I get into the technical details I want to emphasize what I consider the most important a11y skill for a front-end engineer - Succinct communication. You must be able to communicate to a larger team exactly why a particular element is failing WCAG success criteria and provide examples of how to fix it. Don’t fix it for them but help your team understand how to identify the issue and fix it. Don’t simply make the change, be the agent of change.

The most significant technical challenges for eCom sites involve interaction complexity. Micro-interaction components such as carousels, mini shopping carts, pinch zoom, and promotional popup dialogs are transitional and difficult to describe to the visually impaired. The fact that these interactions are actuated with JavaScript makes it impractical to test automatically. I’ve found the best way to find and fix these types of interactions is with a screen reader and then applying state-full ARIA patterns attributes as needed.

Manual Audit

Here I describe a basic 10 minute audit that you can perform just to get a feeling for how accessible a page is. Common issues should be apparent when answering these questions:

  1. Is there a Skip to Main Content Link from the omnibox?

  2. Can a shopper navigate with the tab key and are the focus styles visible?

    Pro ⚡ Tips

    Generally, do not use a tab index value greater than 0. Use tabindex="0" on an A element that does not have an HREF.

    //  Run in browser console or save as a browser snippet.
    //  Remove ALL tabIndex on the entire page - That is a fun thing to do.  ES5
    //  From the entire document remove tabIndex if its value is greater than 0
    [] document.querySelectorAll("[tabIndex]") ).filter(function(el){ // Neodigm 2020
        console.log("-- | " + el.tabIndex );
        if(  el.tabIndex >= 1 ){
            el.tabIndex = "";
    // From the entire document add a tabIndex="0" attrib if an A has no href
    [] document.querySelectorAll("A") ).filter(function(el){ 
        //console.log("== | " + el.tabIndex, el.href );
        if( !el.href ){
            el.tabIndex = 0;

    💡 Always show which element has the focus. In dev tools console click on the 👁️ eye icon and create this expression:


    💡 When debugging keyboard access issues in Chrome make sure that the DevTools panel is disconnected from the browser. If it is connected it shares the tab order with the document you are viewing. This makes it difficult to test issues related to "Skip to Main Content".

  3. Is there off-screen content that receives the focus?

  4. Can a shopper search, filter, and add to cart with a screen reader?

  5. Do landmark elements / roles represent the document’s information hierarchy?

  6. Is the document's accessibility tree well formed (chrome://accessibility/)?

Chrome Extensions

There are some pretty good Chrome extensions that will give you an actionable audit without many false-positives:

  1. Google Lighthouse — I use Lighthouse at least daily to get a feel for not only a11y but performance as well.

  2. Wave — This is the WebAIM extension. What I like most about this is its ability to show you the exact line that has the issue.

  3. aXe — Becoming my new fav, this extension exists solely in the developer tools panel. The results are very in-depth. They also offer a command line version that can be hooked into your CI build script.

    Pro ⚡ Tips

    Install aXe CLI

    npm i @axe-core/cli

    💡 You can then run the A11Y audit from within VSCode terminal or automate via Gulp watch / Github Actions.

JavaScript Keyboard Trap

Keyboard Trap POC snippet - Prevent the user from tabbing outside of a modal dialog.

Circular Keyboard Trap
a55_reveal.aRevAct[i].setAttribute("aria-haspopup", "dialog");
a55_reveal.aRevAct[i].setAttribute("aria-controls", sDialogId);
if( !oIDs[ sDialogId ]){ // A11y update the dialog (inert content) only once
  var eDialog = document.getElementById( sDialogId );
  if( eDialog ){
    eDialog.tabIndex = -1;
    eDialog.setAttribute("role", "dialog");
    eDialog.setAttribute("aria-modal", "true");
    window.addEventListener("focus", function(ev){
        if( a55_reveal.isOpen && (typeof != "undefined") ){
          var eTarget =, bInside = false;
          if(typeof eTarget.tagName != "undefined"){
            while( eTarget.tagName !== "HTML" ){ 
                //  Tab within modal dialog
                if( eTarget.tagName == "A55-REVEAL" ){
                  bInside = true; break;
              eTarget = eTarget.parentNode;
          if( !bInside ){
            ev.preventDefault(); ev.stopPropagation();
      }, true);
  oIDs[ sDialogId ] = true;

Skip to Main Content

Skip to Main Content - CSS Focus rules that make the link visible when focused from the omnibox.

CSS Only Solution - Markup
<a class="js-skip__main--id skip__main"
href="#ltdc-skipmain">Skip to Main Content</a>
CSS Only Solution
a.skip__main:active, a.skip__main:focus {
    background-color: #fff;
    border-radius: 4px;
    border: 2px solid #000;
    color: #000;
    font-size: 1em;
    height: auto; width: 16%;
    left: auto;
    margin: 8px 42%;
    overflow: auto;
    padding: 4px;
    text-align: center;
    top: auto;
    z-index: 1024;
a.skip__main {
    left: -1024px;
    overflow: hidden;
    position: absolute;
    top: auto;
    width: 1px; height: 1px;
    z-index: -1024;

Achieving accessibility nirvana is not easy for an eCommerce site. If you are uninspired, try to think of it in terms of exposing your business to a new group of shoppers who would have trouble shopping at your competitor’s site.

Thanks for reading!

WCAG 508 ARIA JavaScript