Reputation: 12016
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
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
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