javascriptajaxdialogaccessibilityaria-live

How should a dialog announce dynamic content to screen reader users?


I have a <dialog> element which, when opened, requests some content from the server using AJAX. When the content returns (which of course can be any length of time depending on connection speed and amount of content) the new content is then dynamically appended to the dialog.

How can I make screen reader users aware that this content now exists and that they can move to it? Should focus be moved to the content once it is inserted?


I'm using the a11y-dialog library to open the dialog.

I have the container for the dialog set up with aria-live="polite" and add aria-busy="true" once I start the AJAX request.

aria-busy is then set to false once the AJAX request returns and the content is added to the container.

This works to announce the content as soon as it arrives, however, it reads all text entered, which in some cases can be several paragraphs. My experience with the screen reader controls is limited, so I'm unsure if there is a way to interrupt this automatic reading process.

This is the HTML code for the dialog. The AJAX container has the id #dialog-ajax-wrapper.

<div class="dialog js-dialog" id="dialog" hidden>

    <div class="dialog__overlay" tabindex="-1" data-a11y-dialog-hide></div>

    <dialog class="dialog__native" aria-labelledby="dialog-title">
        <div class="dialog__inner">

            <button class="dialog__close" type="button" data-a11y-dialog-hide aria-label="Close dialog window">
                X
            </button>

            <div class="dialog__ajax" id="dialog-ajax-wrapper" aria-live="polite"></div>

            <div class="dialog__loader" aria-hidden="true"><div class="loader"></div></div>

        </div> <!-- /.dialog__inner -->
    </dialog>
</div>

I would expect the fact that content is loading to be announced in someway, which it currently isn't. Then once the content is inserted, it is announced but not read in its entirety.

This is further compounded because focus is transferred to the close button. Since there are no other focusable elements until the content is loaded, tabbing or trying to navigate produces no result which could lead the user to think nothing is available and leave the page.

Is this the right method or is there a better way?


Solution

  • How can I make screen reader users aware that this content now exists and that they can move to it? Should focus be moved to the content once it is inserted?

    It's a bad idea to focus static text or to make it focusable. The user may think that he can interact with the text, what isn't the case. The basic reaction would be "it doesn't work".

    Generally, the rules for placing focus in a dialog is as follows:

    So in your case you are correct, the focus must stay to the OK or close button, and shouldn't be moved away.

    This works to announce the content as soon as it arrives, however, it reads all text entered, which in some cases can be several paragraphs. My experience with the screen reader controls is limited, so I'm unsure if there is a way to interrupt this automatic reading process.

    Don't worry with the text length. Of course there are ways to stop reading before the end, repeating, reading one paragraph, one sentance or one word at a time.

    I encourage you to read documentation or follow toturials about several screen readers. The most popular are Jaws and NVDA under windows, VoiceOver under Mac and iOS, Talkback under Android...

    I would expect the fact that content is loading to be announced in someway, which it currently isn't.

    If loading is fast enough, there's no reason that the loading be announced at all. I hope that it's your case. Foundamentally once a dialog box appears, I wouldn't like to wait a long time for the content.

    If it takes a while to load, It would probably be better if the dialog appears only when everything is loaded. This would remove your fear about what could happen and what the user may think while the dialog content is loading.

    You may show a separate load indicator instead of the empty dialog. IF you do so, don't forget to use aria-live so that loading is announced.

    Then once the content is inserted, it is announced but not read in its entirety.

    When the content become too long, the normal screen reader user will anyway start using navigation shortcuts such as arrow keys or left/right sweeps, rather then waiting that everything is read in a single pass. So don't worry, it's enough if your text stays accessible with this kind of navigation.