In this article, we’ll be taking a look at the structure inside
<input type='color'> elements, browser inconsistencies, why they look a certain way in a certain browser, and how to dig into it. Having a good understanding of this input allows us to evaluate whether a certain cross-browser look can be achieved and how to do so with a minimum amount of effort and code.
Here’s exactly what we’re talking about:
But before we dive into this, we need to get into…
We’ve got a huge problem here: for those who completely rely on a keyboard, this input doesn’t work as it should in Safari and in Firefox on Windows, but it does work in Firefox on Mac and Linux (which I only tested on Fedora, so feel free to yell at me in the comments if it doesn’t work for you using another distribution).
In Firefox on Windows, we can Tab to the input to focus it, press Enter to bring up a dialog… which we then cannot navigate with the keyboard!
I’ve tried tabbing, arrow keys, and every other key available on the keyboard… nothing! I could at least close the dialog with good old Alt + F4. Later, in the bug ticket I found for this on Bugzilla, I also discovered a workaround: Alt + Tab to another window, then Alt + Tab back and the picker dialog can be navigated with the keyboard.
Things are even worse in Safari. The input isn’t even focusable (bug ticket) if VoiceOver isn’t on. And even when using VoiceOver, tabbing through the dialog the inputs opens is impossible.
If you’d like to use
<input type='color'> on an actual website, please let browsers know this is something that needs to be solved!
How to look inside
In Chrome, we need to bring up DevTools, go to Settings and, in the Preferences section under Elements, check the Show user agent shadow DOM option.
Then, when we return to inspect our element, we can see inside its shadow DOM.
In Firefox, we need to go to
about:config and ensure the
devtools.inspector.showAllAnonymousContent flag is set to
Then, we close the DevTools and, when we inspect our input again, we can see inside our input.
Sadly, we don’t seem to have an option for this in pre-Chromium Edge.
The structure inside
The structure revealed in DevTools differs from browser to browser, just like it does for range inputs.
In Chrome, at the top of the shadow DOM, we have a
<div> wrapper that we can access using
Inside it, we have another
<div> we can access with