23
votes

I've written a site that uses jQuery to display a modal popup. It essentially covers the entire viewable area of the screen with an overlay, then shows a DIV that contains the actual popup on top of the overlay. One of the requirements for this project has to do with accessibility.

When the page loads, the screen reader starts reading from the top of the page. When a user clicks on a particular link, we display a modal dialog. My question is: how do I interrupt the screen reader's reading of the main portion of the site and tell it to start reading the dialog text?

My modal container is wrapped in a div like this:

<div id="modalcontainer"  tabindex="0" class="popup" role="dialog" aria-labelledby="dialog-label" >

The jQuery that fires the modal looks like this:

$("#modalLink").click(function (e) {
    e.preventDefault();

    $("#modalcontainer").center();
    $("#modalcontainer").show();
    $("#closeBtnLink").focus();
    $("#wrapper").attr('aria-disabled', 'true');
});

The "closeBtnLink" is the close button within the modal dialog. I would have thought setting the focus on this would instruct the screen reader to start reading from that element.

The "wrapper" element is a SIBLING of the modal dialog. Per a suggestion from another SO user for different reasons, I set "aria-disabled=true" on the wrapper element that contains the entire page. The modal dialog exists as a sibling outside of this container.

My main goal here is to get the screen reader to read the contents of my modal DIV element when they click on a specific link. Any help would be appreciated.

5
I'd set the focus to the content, not the close link. Is there a heading in the dialog?steveax
There is, but for some reason one of the requirements is to set the focus to the close link. This client is EXTREMELY picky about their requirements and if it's in there, there's nothing I can do to change their mind. Major multi-national corporation, since when have their decisions ever been right? :)Scott
There is no consistent way, please read: sitepoint.com/ajax-screenreaders-workPolity
That link is almost 6 years old.Scott
Some reading about modals and accessibility: irama.org/web/dhtml/lightboxFelipeAls

5 Answers

8
votes

This can be accomplished using ARIA role="dialog". you'd have to modify this code for your example, it's vanilla js, so yours will probably be shorter/easier via jQuery.

HTML:


<div role="dialog" aria-labelledby="myDialog" id="box" class="box-hidden" tabindex="-1">
  <h3 id="myDialog">Just an example.</h3>
  <button id="ok" onclick="hideDialog(this);" class="close-button">OK</button>
  <button onclick="hideDialog(this);" class="close-button">Cancel</button>      
</div>

JavaScript:


var dialogOpen = false, lastFocus, dialog, okbutton, pagebackground;

function showDialog(el) {
    lastFocus = el || document.activeElement;
    toggleDialog('show');
}
function hideDialog(el) {
    toggleDialog('hide');
}

function toggleDialog(sh) {
    dialog = document.getElementById("box");
    okbutton = document.getElementById("ok");
    pagebackground = document.getElementById("bg");

    if (sh == "show") {
        dialogOpen = true;

        // show the dialog 
        dialog.style.display = 'block';

        // after displaying the dialog, focus an element inside it
        okbutton.focus();

        // only hide the background *after* you've moved focus out of the content that will be "hidden"
        pagebackground.setAttribute("aria-hidden","true");

    } else {
        dialogOpen = false;
        dialog.style.display = 'none';
        pagebackground.setAttribute("aria-hidden","false");
        lastFocus.focus(); 
    }
}


document.addEventListener("focus", function(event) {

    var d = document.getElementById("box");

    if (dialogOpen && !d.contains(event.target)) {
        event.stopPropagation();
        d.focus();
    }

}, true);


document.addEventListener("keydown", function(event) {
    if (dialogOpen && event.keyCode == 27) {
        toggleDialog('hide');
    }
}, true);  

source: http://3needs.org/en/testing/code/role-dialog-3.html
more reading: http://juicystudio.com/article/custom-built_dialogs.php

6
votes

It is your responsibility as a developer to present the content of a page in a way that makes it readable for the screenreader.

from http://www.anysurfer.be/en/index.html:

  • Use the right HTML tags to structure your documents. By doing so, assistive technologies can translate headings, paragraphs, lists and tables to braille or speech in a comprehensible manner.
  • Make sure that the website is also operable without using the mouse. In most situations, no special actions are required, except if - for instance - you use dropdown menus. This particular guideline is of great importance to visitors that are only able to use the keyboard.
  • You can make your audio and video fragments accessible to visitors with an auditive or visual constraint by adding subtitles or by offering a transcription.
  • Never solely rely on colors to convey structural information. The message ‘The fields in red are mandatory’ has no use for a blind person or someone who is colorblind.
  • A refreshable braille display cannot display images. Therefore, you should add short descriptions for images and graphical buttons. They don't appear on the screen, but they do get picked up by the screenreader software used by the blind and visually impaired.
  • The use of technologies like Flash and JavaScript should be well-considered. Moreover, heavy animations and flickering are very disturbing for people who suffer from dyslexia or epilepsy.

But is ultimately the responsibility of the screen reader to make sure that it stops and starts when it makes sense to the user, if not possible the user should pause the reader itself.

Because of the large variety of screen readers out there, what you are asking seems quite impossible.

2
votes

aria-hidden="true" will make screen readers to not perceive that element and its content, which means that it will not be read out.

aria-label will set the text which assistive technologies (screen readers, etc) will perceive.

http://www.w3.org/TR/wai-aria/states_and_properties

0
votes

Can you use ARIA Live Regions? https://developer.mozilla.org/en/ARIA/Live_Regions Then in Javascript during the modal display, swap the regions with assertive and off.

0
votes

I faced the same issue and solved with following setp's

  • created one more div (#message) inside modal container wrapper to place all the message
  • And set aria-labelledby attribute to the close button to point to the #message container