I have a custom slider implementation. When it's :focus:visible
, I handle the arrow keys (Up
/Left
and Right
/Down
) to move its thumb. I suppose, that's enough to declare the control role="slider"
in desktop browsers.
What should I support on touch screen devices?
MDN says just:
Warning: To change the slider value, touch-based assistive technologies need to respond to user gestures for increasing and decreasing the value by synthesizing key events. Fully test slider widgets using assistive technologies on devices where touch is a primary input mechanism before using the slider role (and all range widgets).
UPDATE I really believe there is no need in a MRE here, because my implementation is pretty simple:
I use the standard draggable behavior for the thumb. There is a lot of draggable implementations, such as one bundled with jQuery UI, but I preferred interact.js draggable (Y-axis locked, i.e. one-dimensional).
To make the control friendly for those, who have difficulties with movements AND screen reader users, I also handle the arrow keys:
function onArrowKey(e)
{
if (mouseDraggingIsInProcess)
return;
if (['ArrowDown', 'ArrowUp', 'ArrowLeft', 'ArrowRight'].includes(e.key))
{
e.stopImmediatePropagation();
e.preventDefault();
if (e.type == 'keydown')
{
const thumbPositionY = match(e)
(
when(e => e.ctrlKey, 1),
when(e => e.shiftKey, (1 + options.stepsCount) / 2),
otherwise(options.stepsCount)
);
if ('ArrowDown' == e.key || 'ArrowRight' == e.key)
onThumbPositionChange(0, thumbPositionY);
else if ('ArrowUp' == e.key || 'ArrowLeft' == e.key)
onThumbPositionChange(0, -thumbPositionY);
}
else if (e.type == 'keyup')
{
reset();
}
}
}
control.on('keydown keyup', onArrowKey);
onThumbPositionChange(0, thumbPositionY);
is exactly the same handler, that is called by the draggable behavior.
Also, I added to the div
the following attribute:
<div aria-label="A joystick. Use arrow keys to move it fast.
Shift makes it move at medium speed. Control makes it move at slow speed.
After releasing the keys it returns to initial position." …>
I would at a minimum make sure you can change the value by both dragging and tapping and test it out with VoiceOver and Talkback to make sure the standard slider controls are working. Compare yours with a standard HTML slider people will be used to using. W3C has some examples of custom slider implementations that work ok with VoiceOver, though the value isn’t read if I double tap, hold, and drag to change the value, so there’s some room for improvement there. You could probably fix that with an aria live region that dynamically updates the value when it’s changed. I would also try it out with voice control software, here are the instructions for sliders in Windows built in voice control.