DEV Community

Mads Stoumann
Mads Stoumann

Posted on • Updated on

Accessible Color Pickers

Most of the Color Pickers I've seen and used, haven't been accessible. They've been touch-friendly, but not keyboard-friendly.

So, I set out to create a Color Picker with range-sliders, which are both touch- and keyboard-friendly (using arrow-keys).

For that, the hsl-format (hue, saturation, lightness) is perfect. "Hue" is the recognisable "rainbow", also often seen as a color wheel.

"Saturation" and "Lightness" are normally "merged" into two overlapping gradients with a single x/y-selector.

Here, they appear as two individual sliders:

full

Implementaion

I recommend using an <input type="text">, since the value of this type supports any string. <input type="color"> only supports a 7-char hex-code.

The Color Picker can be configured with some options as well:

Output-formats

  • cmyk
  • hex (default)
  • hsl
  • rgb

Size

  • full (default)
  • micro (no alpha-channel, use for <input type="color"> ):

micro

  • mini:

mini

And, if you want to use the trigger (the <input> itself) as preview, the value "update" will hide the preview of the Color Picker:

mini-update

Examples:
<input type="text" data-colorpicker="rgb mini">
<input type="text" data-colorpicker="hsl micro update">

Keyboard Shortcuts:

<input>-trigger:

  • ArrowDown : Open ColorPicker.
  • Escape : Close ColorPicker.

ColorPicker:

  • Arrow Keys : Change value on selected input.
  • Enter : Close ColorPicker, set value.
  • Escape : Close ColorPicker, do not set value.
  • Tab : Go to next element. When tabbing away from last input, the ColorPicker wll close and re-focus on the input/trigger.

And finally, here's a CodePen-demo:

Thanks for reading!

Top comments (3)

Collapse
 
supportic profile image
Supportic • Edited

@madsstoumann
How do you access the values of the sliders when the input changed either via auto update or when clicking ok? Non of my event listeners work. Also maybe as enhancement, when you click outside, do not focus the input anymore. I think you made it that way so you keep the focus after pressing ESC while using keyboard only but the focus is not needed when clicking outside.

const logValue = (e) => {
  console.log(e.target.value);
};

const main = () => {
  const colorPickers = document.querySelectorAll('[data-colorpicker]');
  colorPickers.forEach((colorPicker) => {
    let pcr = new ColorPicker(colorPicker, colorPicker.dataset);

    console.log(pcr.value);

    colorPicker.addEventListener('input', logValue, false);
    colorPicker.addEventListener('change', logValue, false);
  });
};
Enter fullscreen mode Exit fullscreen mode
Collapse
 
andreacanton profile image
Andrea Canton

What an astonishing work! There is a github/gitlab repo?

Collapse
 
madsstoumann profile image
Mads Stoumann

Sure! Its in: github.com/madsstoumann/assets
You need the "colorpicker.mjs", "colorlib.mjs" and "range.mjs" from the js-folder, and "c-clp.css" plus "c-rng.css" from the css-folder.