Search code examples
javascripthtmlaccessibilityscreen-readersnvda

NVDA doesn't read aria-describedby with aria-label


I have a simple button.

.icon {
    border: 1px solid black;
    display: inline-block;
    height: 25px;
    text-indent: -999em;
    vertical-align: middle;
    width: 25px;
}

    <a role="button" href="javascript:void(0);" aria-label="select product" aria-describedby="navigation">
        <span id="navigation" class="icon >Enter to open, tab to navigate</span>
    </a>

When I tab to this link, I want to hear "select product button, Enter to open", but NVDA reads only "select product button" without navigation message.

Could someone know how to fix it or somehow provide additional navigation message for button?


Solution

  • 1. Why is aria-describedby not used in your example: aria-describedby is for additional not important informations. Often the title attribute is matched to aria-describedby automatically. (Note: if a label or content is missing the title is matched to the a11y name (i.e.: same thing as aria-label). Due to the fact that it is for additional usage and most developers are using it too often for unimportant things screenreaders don't announce it automatically (There might be shortcuts and settings for screenreader user to force reading those.). There are though exceptions: Most screenreaders will automatically read the description of a dialog for example.

    2. Why your usage of aria-describedby is wrong: You describe how the user should activate this control, but this is clearly not necessary. Actually this is the main function of aria roles and properties. If you describe an element with semantic markup, it informs the user how to interact with it, you don't need to repeat it with words. For example: a <button>, role="button" means if you press enter or space or do a (mouse)click, it will execute the default action of this control (in case of a native button element this can be simply accomplished with a click event).

    3. You can can use aria-haspopup="true", but if you do you must add additional JS: The point above also explains why simply adding <button aria-haspopup="true"> as described by the other answer, would sound great for you in the screenreader, but it is not always the best thing to do.

    In fact <button aria-haspopup="true" aria-label="Settings"> reads "Settings, Menubutton", which might be semantically what you want. But from description it does not mean, this button opens a submenu/popupmenu in the first place. It means, it behaves as a menu button. And a menu button will execute it's default action also if you press "cursor down" (it also allows space/enter).

    This means the linked tutorial with the submenu is bullshit. If you hit cursor down or space it does not open the submenu.

    Here comes also a fun part. If you create a <button aria-haspopup="true" aria-label="Settings"> (including all menu button interactions (i.e.: space, enter, cursor down...) and then open a role="dialog" and move the focus inside this dialog. It would not be what the user would have expected, but it is totally fine/accessible, because your control behaves as described and as soon as the user switches to the dialog, he gets informed, that he is not in a menu, but in a dialog and can interact with it accordingly.