EyeDropper API
Published
EyeDropper API — per Chrome for Developers, the EyeDropper API “enables authors to use a browser-supplied eyedropper in the construction of custom color pickers,” letting a page sample the color of an on-screen pixel instead of shipping its own color-sampling code.
Browser & ecosystem support
Section titled “Browser & ecosystem support”- Legend
- Yes
- Partial
- Flag
- No
- Unknown
| Browser / Platform | Support | Versions | Confidence | Source | Notes |
|---|---|---|---|---|---|
| Chrome (Desktop) | Yes | 95 | high | source | 12 |
| Chrome (Android) | No | — | high | source | 3 |
| Edge (Desktop) | Yes | 95 | high | source | 456 |
| Firefox (Desktop) | No | — | high | source | 7 |
| Firefox (Android) | No | — | high | source | 89 |
| Safari (macOS) | No | — | high | source | 10 |
| Safari (iOS) | No | — | high | source | 1112 |
| Samsung Internet | No | — | high | source | 1314 |
| WebView (Android) | No | — | high | source | 15 |
- Before Chrome 120, the EyeDropper API is not available on ChromeOS. See bug 40720753 (https://crbug.com/40720753).
- Available on Linux X11, but not available on Linux Wayland. See bug 40720753 (https://crbug.com/40720753).
- No Chrome Android support is recorded in browser-compat-data.
- Before Chrome 120, the EyeDropper API is not available on ChromeOS. See bug 40720753 (https://crbug.com/40720753).
- Available on Linux X11, but not available on Linux Wayland. See bug 40720753 (https://crbug.com/40720753).
- Derived by browser-compat-data mirroring from Chrome.
- No Firefox support is recorded in browser-compat-data.
- No Firefox for Android support is recorded in browser-compat-data.
- Derived by browser-compat-data mirroring from Firefox.
- No Safari support is recorded in browser-compat-data.
- No Safari on iOS support is recorded in browser-compat-data.
- Derived by browser-compat-data mirroring from Safari.
- No Samsung Internet support is recorded in browser-compat-data.
- Derived by browser-compat-data mirroring from Chrome Android.
- Implementation tracking: https://crbug.com/40791573.
How to use it
Section titled “How to use it”Per Chrome for Developers, open() “can only be called in response to a user action (like a
button click),” so the call belongs inside the click handler itself. It resolves after the
user selects a pixel, giving access to that pixel’s color in sRGBHex format:
// Minimal, self-contained: create the controls the handler needs, then wire it up.const pickButton = document.createElement('button');pickButton.type = 'button';pickButton.textContent = 'Pick a color';const colorInput = document.createElement('input');colorInput.type = 'color';document.body.append(pickButton, colorInput);
pickButton.addEventListener('click', async () => { const eyeDropper = new EyeDropper(); try { const result = await eyeDropper.open(); colorInput.value = result.sRGBHex; // e.g. "#3366ff" } catch (err) { // Per MDN, AbortError means the user pressed Escape or an AbortController // aborted the selection. if (err.name === 'AbortError') { console.log('Eyedropper selection aborted.'); } else { console.error('Eyedropper pick failed:', err.name, err); } }});How to detect it at runtime
Section titled “How to detect it at runtime”'EyeDropper' in window is false in browsers that do not implement the API. The fallback
branch below actually shows an <input type="color"> swatch instead of the pick button:
function initColorPicker(pickButton, colorInput) { if (!('EyeDropper' in window)) { // No native eyedropper here — hide the pick button and let the user choose a // color with the always-present <input type="color"> swatch instead. pickButton.hidden = true; colorInput.hidden = false; return; } pickButton.hidden = false; pickButton.addEventListener('click', async () => { const eyeDropper = new EyeDropper(); try { const { sRGBHex } = await eyeDropper.open(); colorInput.value = sRGBHex; } catch (err) { // AbortError covers Escape and an AbortController aborting the selection. if (err.name === 'AbortError') { console.log('Eyedropper selection aborted.'); } else if (err.name === 'NotAllowedError') { // open() was not called from a transient user activation. console.error('Eyedropper needs a fresh user gesture.'); } else if (err.name === 'InvalidStateError') { // Another eyedropper is already open. console.error('An eyedropper is already open.'); } else { // OperationError: the selection failed for other reasons. console.error('Eyedropper pick failed:', err.name, err); } } });}Practical checklist
Section titled “Practical checklist”- Per MDN, the EyeDropper API “is not Baseline because it does not work in some of the most widely-used browsers” — feature-detect before constructing one.
- Only call
open()from inside a user-gesture handler — per Chrome for Developers it “can only be called in response to a user action (like a button click).” - Handle the rejected promise from
open()byname: per MDN,AbortErroroccurs when the user aborts the selection by pressing Escape or when anAbortControlleraborts it.NotAllowedErrormeans the call lacked a transient user activation,InvalidStateErrormeans another eyedropper is already open, andOperationErrormeans the selection failed for other reasons. open()accepts anAbortSignal, so an in-progress pick can also be cancelled programmatically when the picker’s host dialog is dismissed.- Per MDN’s browser-compat-data, Chrome for Android does not implement the API, so a mobile-first color picker cannot rely on it at all.
- Desktop support is not uniform across platforms: per MDN’s browser-compat-data the API is
“available on Linux X11, but not available on Linux Wayland,” and “before Chrome 120, the
EyeDropper API is not available on ChromeOS.” Keep the
<input type="color">fallback reachable everywhere rather than assuming a desktop Chromium build can always pick.
Where to go next
Section titled “Where to go next”For the full reference (constructor, open() options, cancellation), see
EyeDropper API.
See also Async Clipboard API for another Chromium-first capability used by editor-style web apps.
← Back to the Compatibility explorer.