Search code examples
accessibilitywai-aria

Is there any guidance on when to choose aria-describedby instead of aria-labelledby?


Is there any guidance on when to choose aria-describedby instead of aria-labelledby?

Reading the MDN guidance on the two attributes, I get the feeling they are similar and interchangeable. Both seem to suggest that they can be used for input labels and other content but many compliance tools do not seem to like aria-describeby on input tags. I hate applying a particular attribute blindly just because a tool says I should and I would prefer to know something concrete about the when and why

Here are the entries on MDN regarding the two aria attributes in question:

aria-labelledby attribute

aria-describedby attribute


Solution

  • They are indeed very similar, there is one key distinction.

    aria-labelledby

    aria-labelledby will overwrite any existing labelling including any semantically derived label.

    For example if you had a <button> and used aria-labelledby the button text would be overwritten by the first item you listed as the label.

    In the following example if you tab to the button (using the mouse over will read the button text in some screen readers) it will read "first label" then "Further information" instead of "this text will not be read".

    <button aria-labelledby="lbl1 lbl2">This text will not be read</button>
    <p id="lbl1">first label</p>
    <p id="lbl2">Further information</p>

    aria-describedby

    aria-describedby on the other hand will read the linked information as additional information. It will read this after the button semantically derived information.

    So in the below example it will read "This text will now be read", "first label" then "Further information". Yet again you need to focus the button (not mouse over) to see this behaviour.

    <button aria-describedby="lbl1 lbl2">This text will now be read</button>
    <p id="lbl1">first label</p>
    <p id="lbl2">Further information</p>

    Limitations

    Warning - support for aria-labelledby and aria-describedby is really not as good as you might think.

    If information is truly important (i.e. the element will not make sense without it) then you should revert to using visually hidden text instead.

    I have a Stack Overflow answer on the class you should use for visually hidden text instead of the built in sr-only class in most libraries.

    Please note there are certain times you cannot use this (i.e. within a <select>s <option>, but for essential information this is the only 100% supported way to do it (all the way back to IE6)

    .visually-hidden { 
        border: 0;
        padding: 0;
        margin: 0;
        position: absolute !important;
        height: 1px; 
        width: 1px;
        overflow: hidden;
        clip: rect(1px 1px 1px 1px); /* IE6, IE7 - a 0 height clip, off to the bottom right of the visible 1px box */
        clip: rect(1px, 1px, 1px, 1px); /*maybe deprecated but we need to support legacy browsers */
        clip-path: inset(50%); /*modern browsers, clip-path works inwards from each corner*/
        white-space: nowrap; /* added line to stop words getting smushed together (as they go onto seperate lines and some screen readers do not understand line feeds as a space */
    }
    <button>This text will now be read <span class="visually-hidden">,first label</span> <span class="visually-hidden">,Further information</span></button>