Saturday, April 27, 2024
HomeCSSAccessible Toggles

Accessible Toggles


I just lately obtained some nice recommendation from Scott O’Hara on bettering the accessibility of a demo that includes a reduced-motion toggle (for this text). The demo units the play-state of the animation relying on the consumer’s movement preferences (utilizing the prefers-reduced-motion media question). Customers may additionally click on the button to toggle movement on and off, which additionally adjustments the textual content of the button to “Activate movement” or “Flip off movement”. Right here’s the unique model:

See the Pen
Decreased-motion toggle
by Michelle Barker (@michellebarker)
on CodePen.

Scott identified that some screenreaders wouldn’t announce the change to the button textual content when the button is clicked.

I’ve one suggestion although, per the accessibility of the toggle management. Altering the accessible title of the button won’t be persistently introduced by display readers. NVDA and JAWS particularly don’t announce the title change – I made a fork of your pen to show an alternate strategy to code the toggle management.

Let’s stroll by means of the code and add Scott’s advised enhancements with an easier model of the demo, so we will perceive what’s going on extra clearly from an accessibility viewpoint. For the aim of this text we’ll simply give attention to a button that performs or pauses the animation when clicked, with out regarding ourselves with the extra complexity of the unique, which incorporates checking the consumer’s system-level movement preferences and localStorage. (In the event you’re you may all the time return and discover the remaining demo and accompanying article.)

That is the demo we’ll use as a place to begin:

See the Pen
Decreased-motion toggle (fundamental)
by Michelle Barker (@michellebarker)
on CodePen.

Right here’s the button in our HTML:

<button data-toggle hidden>Flip off movement</button>

It contains the hidden attribute, as with out JS the button doesn’t do something, and we wouldn’t need to confuse customers who don’t have JS enabled, or for whom JS fails to load. So we’ll conceal it initially, then take away this attribute with JS.

In our JS code, we first set a variable for whether or not the animation ought to presently be paused, with an preliminary worth of false (because the animation will probably be enjoying to start with). We’ll show our button by eradicating the hidden attribute.

When the button is clicked, we’ll toggle the shouldPauseAnimation variable. Then we’ll set a customized property (to alter the play state of the animation in CSS), and replace the button textual content:

const toggle = doc.querySelector('[data-toggle]')

let shouldPauseAnimation = false

// The button is hidden initially, because it will not work with out JS. We have to make it seen
toggle.hidden = false

toggle.addEventListener('click on', () => {
shouldPauseAnimation = !shouldPauseAnimation

if (shouldPauseAnimation) {
// Pause animation
toggle.innerText = 'Activate movement'
doc.physique.type.setProperty('--playState', 'paused')
} else {
// Play animation
toggle.innerText = 'Flip off movement'
doc.physique.type.setProperty('--playState', 'working')
}
})

This toggles the customized property used within the CSS like so, with its authentic default worth:

.circle {
animation-play-state: var(--playState, working);
}

We now have a working movement toggle (hooray!). Sadly, as Scott defined, some screenreaders received’t announce the up to date button textual content on click on. Let’s add Scott’s enhancements.

First, we’ll replace the button’s HTML, so the textual content that informs the consumer of the present “on/off” state is inside a <span> with the aria-hidden attribute:

<button data-toggle hidden>
Toggle movement
<span aria-hidden="true" data-btn-text>: Off</span>
</button>

To a screenreader, the button will now merely say “Toggle movement”, with no indication of the state. We’ll give the button a job of swap, and add the aria-checked attribute with a worth of true, to point an “on” state:

<button data-toggle hidden function="swap" aria-checked="true">
Toggle movement
<span aria-hidden="true" data-btn-text>: On</span></span>
</button>

In our JS code, we’ll replace each the textual content contained in the <span>, and the aria-checked attribute (along with toggling the --playState customized property:

const toggle = doc.querySelector('[data-toggle]')
const buttonText = doc.querySelector('[data-btn-text]')

let shouldPauseAnimation = false

toggle.hidden = false

toggle.addEventListener('click on', () => {
shouldPauseAnimation = !shouldPauseAnimation

if (shouldPauseAnimation) {
// Pause animation
buttonText.innerText = ': Off'
toggle.setAttribute('aria-checked', 'false')
doc.physique.type.setProperty('--playState', 'paused')
} else {
// Play animation
buttonText.innerText = ': On'
toggle.setAttribute('aria-checked', 'true')
doc.physique.type.setProperty('--playState', 'working')
}
})

The result’s a extra accessible demo:

See the Pen
Toggle swap for movement (fundamental) with accessibility enhancements
by Michelle Barker (@michellebarker)
on CodePen.

The identical rules might be utilized to many various kinds of toggles, reminiscent of a darkish/mild mode toggle.

Learn extra in regards to the aria-switch function.

RELATED ARTICLES

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Most Popular

Recent Comments