Reputation: 2149
I am trying to build a Toggle button which has two states, Edit and Preview. My demo is here:
https://codepen.io/yu-zhang/pen/rNmPyxG?editors=1111
<button aria-pressed="true"
id="speakerPower" class="switch">
<span aria-label="edit">edit</span>
</button>
button.switch {
margin: 0;
padding: 0;
width: 70px;
height: 26px;
border: 2px solid black;
display: inline-block;
margin-right: 0.25em;
line-height: 20px;
vertical-align: middle;
text-align: center;
font: 12px "Open Sans", "Arial", serif;
}
button.switch span {
padding: 0 4px;
pointer-events: none;
}
button[aria-pressed="true"] {
background: #262;
color: #eef;
}
button[aria-pressed="false"] {
color: #a;
}
label.switch {
font: 16px "Open Sans", "Arial", sans-serif;
line-height: 20px;
user-select: none;
vertical-align: middle;
-moz-user-select: none;
-ms-user-select: none;
-webkit-user-select: none;
-o-user-select: none;
}
document.querySelectorAll("button").forEach(function(theSwitch) {
theSwitch.addEventListener("click", handleClickEvent, false);
});
function handleClickEvent(evt) {
let el = evt.target;
if (el.getAttribute("aria-pressed") == "true") {
el.setAttribute("aria-pressed", "false");
el.textContent= 'preview';
el.setAttribute("aria-label", "preview");
} else {
el.setAttribute("aria-pressed", "true");
el.textContent = 'edit';
el.setAttribute("aria-label", "edit");
}
}
But the strange thing is: VoiceOver + Chrome(92.0.4515) reads out the aria-labels while toggling but VoiceOver + Safari(14.1.2) does not read out the aria-labels.
Any ideas?
Upvotes: 0
Views: 1427
Reputation: 17435
You are changing both the aria-pressed
state and the aria-label
property. It's important to know the difference between a state and a property, even though both begin with "aria".
When changing a state, you typically get an automatic announcement by the screen reader ("pressed/unpressed", "checked/unchecked", "expanded/collapsed") of the state change.
When you change a property, no such "free" announcement is made.
You'll see/hear differences depending which screen reader and which browser you're using. Sounds like you're getting the desired behavior in chrome but not safari. It's undefined which one is correct since changes in properties don't have to be announced.
To work around it, you can have a hidden aria-live="polite"
region. In your click handler, just update the innerHTML
of the live region with the new label and it'll be announced. I don't know if that will cause double announcements on chrome.
You'll also want to visually hide the live region so you can't see it but you can't make it display:none
because then the aria-live won't be announced.
<div class="sr-only" aria-live="polite" id="foo"></div>
(See What is sr-only in Bootstrap 3? for info on the "sr-only" class.)
In your click handler, get the "foo" element and change its innerHTML to "preview" or "edit".
Upvotes: 1