EyeDropper API: sampling on-screen colors
Published
In one line: 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 any on-screen pixel — including pixels outside the browser window — without shipping its own color-sampling code.
Creating and opening an eyedropper
Section titled “Creating and opening an eyedropper”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 — pasting it
at the top level of a script will not start the eyedropper:
const pickButton = document.createElement("button");pickButton.textContent = "Pick 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) { // Rejects if the user cancels the pick, e.g. by pressing Escape. console.log("Eyedropper pick cancelled:", err); }});The open() method, per Chrome for Developers, “returns a promise that resolves after the
user selects a pixel on the screen,” and the resolved value gives “access to the pixel’s
color in sRGBHex format (#RRGGBB).” The promise rejects when the user cancels instead
of picking a pixel; the example handles that rejection with try/catch.
User-gesture requirement
Section titled “User-gesture requirement”Chrome for Developers is direct about the activation requirement: “the API doesn’t
actually let the eyedropper mode start without user intent. The open() method can only
be called in response to a user action (like a button click).” Calling open() outside a
click or similar user gesture handler will not start the eyedropper.
Cancelling an open eyedropper
Section titled “Cancelling an open eyedropper”open() also accepts an AbortSignal so an in-progress pick can be cancelled
programmatically, in addition to the user pressing Escape:
const controller = new AbortController();eyeDropper.open({ signal: controller.signal }).catch(() => { // Rejects if the user cancels (e.g. presses Escape) or the signal aborts.});// Elsewhere, e.g. on a "Cancel" button:controller.abort();Feature detection and fallback
Section titled “Feature detection and fallback”"EyeDropper" in window is false in every browser that doesn’t implement the API
(Firefox, Safari). The fallback branch below actually shows the <input type="color">
swatch instead of the pick button, rather than just noting that it should:
function initColorPicker(pickButton, colorInput) { if (!("EyeDropper" in window)) { // No native eyedropper here — hide the pick button and let users pick 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) { // Rejects if the user cancels the pick, e.g. by pressing Escape. console.log("Eyedropper pick cancelled:", err); } });}
const pickButton = document.createElement("button");pickButton.textContent = "Pick color";const colorInput = document.createElement("input");colorInput.type = "color";colorInput.hidden = true;document.body.append(pickButton, colorInput);initColorPicker(pickButton, colorInput);Where it is supported
Section titled “Where it is supported”Per MDN, the EyeDropper API “is not Baseline because it does not work in some of the most widely-used browsers.” Per Chrome for Developers, the API is supported “on Chromium-based browsers like Edge or Chrome as of version 95”; per caniuse’s tracking of the feature, support also extends to Opera. Chrome for Developers’ own walkthrough runs the demo “on Windows or Mac,” consistent with the API being desktop-only in Chromium’s implementation. Firefox and Safari do not implement the EyeDropper API.
Practical checklist
Section titled “Practical checklist”- Feature-detect
"EyeDropper" in windowbefore constructing one — support is limited to Chromium desktop browsers (Chrome/Edge 95+), per MDN and Chrome for Developers. - Only call
open()from inside a user-gesture handler (e.g. a click listener) — per Chrome for Developers, it “can only be called in response to a user action.” - Handle the rejected promise from
open()— it rejects if the user cancels the pick (for example by pressing Escape) instead of selecting a pixel. - Pass an
AbortSignalif your UI needs to cancel an open eyedropper programmatically, such as when the picker’s host dialog is dismissed. - Provide a fallback color input (e.g.
<input type="color">) for browsers withoutEyeDropper, since Firefox and Safari do not implement it.