Search code examples
htmlaccessibility

Setting up difficulty icons for a screen reader


I have an online course with a difficulty rating that is displayed as a variation of the following:

<div class="course-difficulty">
    <label>Difficulty: </label>
    <span class="fas fa-star"></span>
    <span class="fas fa-star"></span>
</div>

What would be the best practise for labelling this for screen readers? I can calculate the star rating, so the label could logically be applied to the parent div as "Difficulty 2" for example, or should this be for the individual icons?


Solution

  • A couple of things, first the use of a <label> here doesn't quite work. <label>s are designed to be linked to interactive elements (inputs).

    If this is display only (i.e. you cannot cast a vote on the difficulty) then the answer is simple:

    .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 */
    }
    <!-- option 1 invisible text (screen reader only text) -->
    <div class="course-difficulty">
        <p>Difficulty: </p>
        <div aria-hidden="true">
            <span class="fas fa-star"></span>
            <span class="fas fa-star"></span>
        </div>
        <span class="visually-hidden">2 out of 5</span>
    </div>
    
    <!-- option 2 aria-label -->
    <div class="course-difficulty">
        <p aria-label="Difficulty: 2 out of 5">Difficulty: </p>
        <div aria-hidden="true">
            <span class="fas fa-star"></span>
            <span class="fas fa-star"></span>
        </div>
    </div>

    There are two variations there.

    In both options we wrap the stars in an aria-hidden div to hide them from a screen reader (as some screen readers may try to read the icons). We also change the label out for a paragraph as it makes more sense.

    In the first option we use visually-hidden text to hide the text visually but make it available to screen readers, explaining the difficulty (and out of how many "stars").

    In the second option we use an aria-label to override the text to include the difficulty rating.

    I personally prefer option 1 due to the fact that it has the best compatibility with screen reader / browser combinations and works on text only browsers (which some braille users prefer to use).

    However there is nothing wrong with using aria-label as that will now work on 99% of screen reader / browser combinations and the edge cases are minimal.

    If the system does allow voting then you would need to use radio buttons etc. and if that is the case let me know and I can help you with that.