Help with web accessibility problem for screen readers - ARIA

gala_water
2023-11-21T20:58:36Z

I'm attempting to make my company's online software documentation ADA-accessible. We have several JavaScript elements that are currently not accessible to a screen reader. The one I'm working on is a set of tabs that show/hide content depending on which one you click. I am trying to use ARIA tags to make the tabs accessible. I have based my code off of this page, with some modifications. Namely, they use tags as the active element and I do not want to use tags.

While I'm able to get the tabs to work fine for me (a sighted person), testing with a screen reader shows mixed results. I can get the tabs to work using the Windows Narrator screen reader on Microsoft Edge in Windows 10, but not Chrome or Firefox in Windows 11. In those configurations, it is impossible to switch tabs. (I haven't tested every possible permutation, but it's probably a browser issue.) I don't know why this is happening because I have set up all my ARIA tags, and it does work on Edge.

Can anyone help me understand what I'm doing wrong so I can debug the issue and improve the code? Requirements are:

The first tab must be selected (showing content) by default. Other tab content must be hidden by default, except the tab button to click on

Sighted users must be able to navigate between tabs by clicking on the tab headers via mouse

Visually impaired users must be able to navigate between tabs via keyboard/screen reader

The presence, function, and usage of the tabs must be clear to the screen reader

I do not want to use an tag nested in the as the active element because this causes the page to jump around when sighted users click on it. I would like the entire "button" (right now, the tag) to be clickable.

Must work on all/most common browsers and popular operating systems

I suspect this is a JS issue, but I'm at a loss here and I don't know how to proceed.

Click to view HTML


Example 1
Example 2
Example 3



Example 1 content goes here



Example 2 content goes here



Example 3 content goes here


Click to view CSS

ul.tabs-list {
	margin-left: 2px;
	margin-right: 2px;
	padding: 0px;
	list-style: none;
	position: relative;
    line-height: 8pt;
}

ul.tabs-list:after
{
	position: absolute;
	content: "";
	width: 100%;
	bottom: 0;
	left: 0;
	border-bottom: 1px solid #ddd;
}

ul.tabs-list li {
	color: #333;
	display: inline-block;
	padding: 10px 10px;
	cursor: pointer;
	position: relative;
	z-index: 0;
}

ul.tabs-list li.current {
	background: #fff;
	color: #d9232e;
	border-top: 1px solid #ddd;
	border-bottom: 0px solid white;
	border-left: 1px solid #ddd;
	border-right: 1px solid #ddd;
	z-index: 100;
}

ul.tabs-list li:hover {
	background: #c2c2c2;
	color: #000;
	display: inline-block;
	padding: 10px 10px;
	cursor: pointer;
	border: 1px solid transparent;
}

ul.tabs-list li.current:hover {
	background: #fff;
	color: #d9232e;
	margin-left: 0px;
	border-top: 1px solid #ddd;
	border-bottom: 1px solid transparent;
	border-left: 1px solid #ddd;
	border-right: 1px solid #ddd;
	z-index: 2;
}

div.tab-panel {
	display: none;
	background: #ededed;
	padding: 15px;
	background-color: transparent;
}

div.tab-panel.current {
	display: inherit;
}

Click to view JavaScript

$(function(){
  var index = 0;
  var $tabs = $('li.tab');

  $tabs.bind(
  {
    // on keydown,
    // determine which tab to select
    keydown: function(ev){
      var LEFT_ARROW = 37;
      var UP_ARROW = 38;
      var RIGHT_ARROW = 39;
      var DOWN_ARROW = 40;

      var k = ev.which || ev.keyCode;

      // if the key pressed was an arrow key
      if (k >= LEFT_ARROW && k <= DOWN_ARROW){
        // move left one tab for left and up arrows
        if (k == LEFT_ARROW || k == UP_ARROW){
          if (index > 0) {
            index--;
          }
          // unless you are on the first tab,
          // in which case select the last tab.
          else {
            index = $tabs.length - 1;
          }
        }

        // move right one tab for right and down arrows
        else if (k == RIGHT_ARROW || k == DOWN_ARROW){
          if (index < ($tabs.length - 1)){
            index++;
          }
          // unless you're at the last tab,
          // in which case select the first one
          else {
            index = 0;
          }
        }

        // trigger a click event on the tab to move to
        $($tabs.get(index)).click();
        ev.preventDefault();
      }
    },

    // just make the clicked tab the selected one
    click: function(ev){
      index = $.inArray(this, $tabs.get());
      setFocus();
      ev.preventDefault();
    }
  });

  var setFocus = function(){
    // undo tab control selected state,
    // and make them not selectable with the tab key
    // (all tabs)
    $tabs.attr(
    {
      tabindex: '-1',
      'aria-selected': 'false'
    });

    // hide all tab panels.
    $('.tab-panel').removeClass('current');

    // make the selected tab the selected one, shift focus to it
    $($tabs.get(index)).attr(
    {
      tabindex: '0',
      'aria-selected': 'true'
    }).focus();

// handle current class (for coloring the tabs)
    $($tabs.get(index)).siblings().removeClass('current');
    $($tabs.get(index)).addClass('current');

    // add a current class also to the tab panel
    // controlled by the clicked tab
    $("#"+$($tabs.get(index)).attr('aria-controls')).addClass('current');
  };
});

Comments URL: https://tildes.net/~comp/1cbl/help_with_web_accessibility_problem_for_screen_readers_aria

Votes: 12

Comments: 5