gene b.
gene b.

Reputation: 12016

Hide Element but Preserve for Screen Readers (can't use display:none, visibility:hidden, or opacity:0)

I have an audio-element in my HTML whose only purpose is to make an announcement to blind users via a Screen Reader. It's a DIV, but it's invisible to regular users.

The way to announce something is by creating an element with role=alert (no other way to do it, there's no JS function to directly "speak" to a reader, for example):

<!-- This element can be dynamically added OR shown (via JS) to make a Screen Reader announcement -->
<div role="alert">This will be announced to Screen Readers.</div>

However, I can't have this "audio assistant" element be visible to regular users.

1) Can't use display: none; -> the Screen Reader won't pick it up

2) Can't use visibility: hidden; -> the Screen Reader won't pick it up

3) Can't use opacity: 0; -> because space is taken up, layout must be exactly the same

I found this solution: https://stackoverflow.com/a/25339638/1005607

div { position: absolute; left: -999em; }

This works great, it solves my problem. But it's a bit of a hack. I wanted to ask: Is there a better, more standard way to solve this problem?

Upvotes: 4

Views: 6499

Answers (2)

slugolicious
slugolicious

Reputation: 17535

It's a common practice to use CSS to visually hide an element but allow it to be discoverable by screen reader users. It's not necessarily considered a "hack".

There are more CSS properties needed than what you tried. See What is sr-only in Bootstrap 3? for details.

Also, you can search for the "visually-hidden" class.

Both sr-only and visually-hidden are common names used to name the class that visually hides elements.

Also, your understanding of role="alert" isn't quite accurate.

The way to announce something is by creating an element with role=alert (no other way to do it, there's no JS function to directly "speak" to a reader, for example):

role="alert" has an implicit aria-live="assertive". Elements with aria-live will announce changes to that element to screen readers. It will not automatically announce that element. For example,

<div id="foo" aria-live="polite"></div>
<button onclick="document.getElementById("foo").innerHTML = 'hello'">update</button>

When I click on the button, text will be injected into the <div> and the new text will be announced.

In general, you want to use aria-live="polite" and not aria-live="assertive". When you use role="alert", you get aria-live="assertive".

So if your page is updating its contents, then using aria-live is the right thing to do. But it does not cause something to be announced just because your page loaded.

The screen reader user has many ways to navigate a website using quick navigation keys defined in the screen reader (such as H to go to the next heading [h1, h2, h3, etc], or T to go to the next table, or L to go to the next list, etc.), provided your HTML is using semantic elements (such as <h1>, <table>, <ul>, etc). If you have text that is hidden to sighted users, then that text can be found by screen reader users without you forcing it to be read automatically.

Upvotes: 2

Wayne Allen
Wayne Allen

Reputation: 1745

I'm not sure if this is a "better" way, but this will hide it in place.

div {
  overflow:hidden;
  height:0;
  width:0;
}

Upvotes: 3

Related Questions