react-compare-slider
react-compare-slider copied to clipboard
A11y support
Hello. Are you planning to add accessibility support (keyboard navigation and aria attributes for screen readers)? Right now it's impossible to move the handle using the keyboard, and there is no way to know current position of the handle if you're using a screen reader. Also as the items are rendered in reverse order (item 2 - item 1) if you're using a screen reader it will read the content in a reverse order as well (first the content of the right block and then the content of the left block).
Hi @acromatica, thanks looking into the accessibility issues!
I've been meaning to resolve the attributes for a while but wasn't able to settle on a good solution. Do you know which attributes would be best for the position, and if there's a way to relate the position to the two items?
The keyboard navigation should be easy enough to add (there was a previous discussion where this was implemented with custom event bindings). I think there would also need to be a new prop to set how much to increment the position by on key press too.
The ordering of the items should be fairly trivial to resolve, I think they could be switched in the render and reordered using CSS order
as its only presentational.
I'll start looking into some solutions, let me know if you have any suggestions :)
Hi Ricky, for sure! The interactions of this slider are very similar to a range selector, so you should look into ARIA slider role: https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/slider_role
The attributes you need to add to the handle element:
-
tabindex="0"
: this way you'll be able to use it from the keyboard; -
role="slider"
: screen readers will prompt the users to interact with it as with a range selector; -
aria-valuemin="0"
: min value; -
aria-valuemax="100"
: max value; -
aria-valuenow="50"
: current value, it should update every time the position of the handle changes; -
aria-valuetext="..."
: here goes the text that describes what's in the slider. I'd suggest something like "50% of [item 1 description] shown/revealed next to [item 2 description]". In case of images you could use alt texts for the descriptions, but I think it should be a new prop so it's possible to add the text that better describes the purpose of item 1 and item 2.50%
bit should update as the position of the handle changes.
Alternatively, instead of aria-valuetext
, you could use a liveregion that would describe what's happening in the slider. For example, something like this:
<span class="liveregion" aria-live="polite">50 Percent of [item 1 description] revealed next to [item 2 description]</span>
If you choose this approach you should to add some kind of delay between the last update of the handle's position and the update of the text inside of the liveregion, because screen readers will read the text each time it changes. So if a user is pressing an arrow key repeatedly, multiple times per second, it's better to wait till they stop and only after that update the text, so they don't hear the text from the liveregion while they're still updating the position of the handle.
Liveregion should be hidden visually and from the screen readers unless the handle is focused (we don't want screen readers to read this text randomly when users don't interact with the slider), so css should be something like:
.liveregion {
display: none !important; /* Hide visually and from the screen readers */
border: 0 !important;
clip: rect(1px, 1px, 1px, 1px) !important;
-webkit-clip-path: inset(50%) !important;
clip-path: inset(50%) !important;
height: 1px !important;
margin: -1px !important;
overflow: hidden !important;
padding: 0 !important;
position: absolute !important;
width: 1px !important;
white-space: nowrap !important;
}
.handle:focus ~ .liveregion {
display: block !important; /* Will be "visible" only for the screen readers, but still hidden visually */
}
Re the ordering of the items, css order is a great idea 👍 Screen readers will ignore css order and will read the content in the order it appears in the markup.
Hope this makes sense, feel free to ping me if you have any questions :)
That's awesome @acromatica, thanks for the detailed info 🙌 I'll start adding the features this week.
Any update?
No progress yet @mbcod3. I'll hopefully get sorted in the next month or so.
Hey @acromatica, I finally got around to implementing this, there's some testing and minor issues to resolve in Safari (keyboard nav back and forth doesn't move consistently) before releasing but feel free to preview it at https://react-compare-slider-git-feature-a11y-support-nerdyman.vercel.app/
This has been released in v3!
npm install react-compare-slider@latest
yarn add react-compare-slider@latest
pnpm install react-compare-slider@latest