Is there an equivalent to the "alt" attribute for div elements?
Solution 1:
There are two ways (which can be combined) to have screen reader to read alternative text:
-
Anything with ARIA role
img
can (MUST) havealt
attribute. See WAI-ARIA img role.<div role="img" alt="heart"> ♥︎ </div>
UPDATE: In 2017 the WAI-ARIA document was changed and the following text does not apply anymore. See comments below.
-
If an element contain actual text, that just need different reading, you should set ARIA role to
text
and addaria-label
with whatever you want to be read by the screen reader. See WAI-ARIA text role.<div role="text" aria-label="Rating: 60%"> Rating: ★★★☆☆︎ </div>
Do not mismatch it with aria-labeledby
which should contain ID of an related element.
-
You can combine the previous two cases into one using two ARIA roles and adding both
alt
andaria-label
:<div role="img text" alt="heart" aria-label="heart"> ♥︎ </div>
When more ARIA roles are defined, browser should use the first one that is supported and process the element with that role.
One last important thing is that you must set page type to HTML5 (which support ARIA by design).
<!DOCTYPE html>
Using HTML4 or XHTML requires special DTD to enable ARIA support.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML+ARIA 1.0//EN"
"http://www.w3.org/WAI/ARIA/schemata/xhtml-aria-1.dtd">
Solution 2:
Try role="listitem"
or role="group"
and aria-labelledby="shopping cart items"
. See Example 1. The 2
is text content which should be read by screen reader already with the attribute read as context to the content. Refer to this section.
UPDATE 2
Add aria-readonly=true
role=textbox
if you use an input. If there are doubts whether to use aria-label
or aria-labelledby
, read this article. In the documentation for JAWS and testing it myself supports the fact that aria-label
is ignored. Furthermore, semantics are very important when accessibility is your concern. Using a div when you could use an input is not semantically sound and like I said before, JAWS would accept a form element more readily than a div. I assume that this "shopping cart" is a form or part of a form, and if you don't like it's borders, input {border: 0 none transparent}
or use <output>
* which would be A+ as far as semantics are concerned.
Sorry, @RadekPech reminded me; I forgot to add that using aria-labelledby
needs visible text and that the text needs an id which is also listed as the value(s) of aria-labelledby
. If you don't want text because of aesthetics, use color: transparent
, line-height: 0
, or color:<same as background>
. That should satisfy visibility as far as the DOM is concerned* and still be invisible to the naked eye. Keep in mind these measures are because JAWS ignores aria-label
.
*untested
EXAMPLE 3
<span id="shopping">Shopping</span>
<span id="cart">Cart</span>
<span id="items">Items</span>
<input id='cart' tabindex="0" aria-readonly=true readonly role="textbox" aria-labelledby="shopping cart items" value='2'>
UPDATE 1
For JAWS, you probably have to configure it a little:
- Click the Utilities menu item.
- Then Settings Center.
- Speech and Sounds Schemes
- Modiy Scheme...
- HTML Tab
In this particular dialog box, you can add specific attributes and what is said when an element is tabbed to. JAWS will respond to form elements easier because they can trigger the focus
event. You'll have an easier time doing Example 2 instead:
EXAMPLE 1
<div id=myCoolDiv tabindex="0" role="listitem" aria-labelledby="shopping cart items"> 2 <div>
EXAMPLE 2
<input id='semantic' tabindex="0" role="listitem" aria-labelledby="shopping cart items" value='2' readonly>
Solution 3:
You can just put a title
tag in the div which will do the same as an alt
tag like so:
<div title="I AM HELLO WORLD">HELLO WORLD</div>
"I AM HELLO WORLD" will be printed once you move your cursor around it on a browser
Solution 4:
In case you use Bootstrap Framework there is a quick and easy solution. You should use sr-only
or sr-only sr-only-focusable
Bootstrap's CSS classes in a span
element where your screen-reader-only
text will be written.
Check the following example, a span
element with class glyphicon glyphicon-shopping-cart
is also used as cart icon.
<div id="myCoolDiv">
<h5>
<span class="glyphicon glyphicon-shopping-cart"></span> 2
<span class="sr-only sr-only-focusable" tabindex="0">shopping cart items</span>
</h5>
<div>
Screen Reader Output: "two shopping cart items"
- provided by Fangs Screen Reader Emulator Addon for Firefox
You can find the above working example in this: Fiddle
As suggested by Oriol, in case you don't use Bootstrap Framework then simply add the following in your CSS file.
.sr-only {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
border: 0;
}
.sr-only-focusable:active,
.sr-only-focusable:focus {
position: static;
width: auto;
height: auto;
margin: 0;
overflow: visible;
clip: auto;
}