1
votes

I have a simple text that gets updated on an action and I want that to be announced by the screen reader. But I don't want that text to be visible on the web page. I tried display: none and visibility: hidden, but seems like they are not accessible by the screen reader softwares. I found a way to make this work - that is by absolute positioning the element all the way with negative 999999 value which will make it off screen and hidden from the webpage. I am not really a fan of this solution. Is there a more elegant way to achieve this?

<span class="aria-invisible" aria-live="polite">5 selections have been made.</span>

.aria-invisible {
   display: none; //either of these two attributes
   visibility: hidden;
}
3

3 Answers

8
votes

A better solution to the bootstrap "sr-only" class.

There are numerous problems with the Bootstrap "sr-only" class.

  1. First of all you will see from this discussion that a negative margin can cause issues on VoiceOver.

  2. Secondly you must account for words wrapping one per line as screen readers do not read line breaks

  3. Finally clip has been deprecated.

To fix point 1 simply don't add a negative margin.

To fix point 2 add white-space: no-wrap to ensure words do not end up 'one per line' and cause words to get smushed together.

To fix point 3 we add clip-path: inset(50%) as this clips to a 0px square, we keep clip as at the moment this has great coverage, clip-path is used to future-proof your solution.

Please find below a much more robust class, as of yet I have not found a screen reader / browser combo that does not work as expected with this.

I have this class on a few different forums being tested, so far so good but if someone can find a problem with it please let me know as I will be submitting it everywhere.

.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 */
}
<p>visible text <span class="visually-hidden">hidden text</span></p>
0
votes

I did encounter this problem in the past. Bootstrap has this sweet class sr-only that actually hides the content on the webpage but is accessible by the screen readers. You can check this link

Moreover, if you are not using bootstrap, you can simply implement the class yourself in your code.

.aria-invisible {
      border: 0; 
      clip: rect(0 0 0 0); 
      height: 1px;  
      margin: -1px;
      overflow: hidden;
      padding: 0;
      position: absolute;
      width: 1px;
    }
<span class="aria-invisible">5 selections have been made. </span>

I hope this helps.

0
votes

Using aria-label attributes is the way to do (example below)

Is there a more elegant way to achieve this?

Do not hide the element. Yes. I am not answering your question, but I am addressing the problem.

Screenreaders are only a subpart of assistive technologies used by a small part of people targeted by accessibility guidelines.

Imagine using a screen magnifier for instance where you do not have a global view on the full screen. Imagine having some cognitive disabilities which makes difficult for you to count or remember elements.

If you do consider that an information is important for blind people, then it's surely is for them AND for other people.

Now, instead of it being a long text, it can be a small counter with appropriate aria labelling:

<div role="status" aria-live="polite" aria-label="5 selections have been made.">
  5 selections
</div>