Skip to content

API Reference

The <color-input> element accepts these HTML attributes:

The value attribute sets the color using standard CSS color syntax.

<color-input value="oklch(70% 20% 240)"></color-input>
Value
oklch(70% 20% 240)
Color Space
oklch
Gamut
Contrast Color
View Code
<color-input value="oklch(70% 20% 240)"></color-input>

Accepted inputs include common CSS formats such as:

  • hex colors
  • rgb() / hsl() / hwb()
  • lab() / lch() / oklab() / oklch()
  • color(display-p3 ...), color(rec2020 ...), color(prophoto-rgb ...), and similar color(...) forms

The colorspace attribute controls which editing space the UI uses.

<color-input
value="color(display-p3 0.3 0.7 0.95)"
colorspace="oklch"
></color-input>

When this changes, the component converts the current color into the requested space and rebuilds the controls to match.

The theme attribute controls the visual appearance:

  • auto (default) - Respects user’s system preference
  • light - Always uses light theme
  • dark - Always uses dark theme
Value
oklch(65% 20% 280)
Color Space
oklch
Gamut
Contrast Color
View Code
<color-input value="oklch(65% 20% 280)"></color-input>

The no-alpha attribute hides the alpha channel control from the color picker. When present, users cannot modify the alpha/opacity value through the UI, though the alpha value is still preserved in the color.

<color-input value="red" no-alpha></color-input>
Value
red
Color Space
oklch
Gamut
Contrast Color
View Code
<color-input value="red" no-alpha></color-input>

Every <color-input> now includes an inline text field for editing the current color string. It accepts anything the CSS Color Level 4 parser understands and keeps the sliders, preview, and computed properties in sync as you type.

  • Validation runs on every keystroke. When parsing fails the host gains a data-error attribute, the textbox sets aria-invalid="true", and the inline error message becomes visible.
  • Restyle the field with ::part(input) and target invalid states with [data-error].
  • A successful parse can also update the active colorspace if the entered syntax implies a different space.
<color-input value="#9333ea"></color-input>

Hover or focus the preview area to reveal a copy button. Activating it copies the current color string with navigator.clipboard.writeText() and shows a “Copied!” status message inside the panel. No configuration is required—the control works for every supported color space, including hex.

Hover or focus the preview area to reveal an eye dropper button to the left of the copy button. Activating it opens the native browser eye dropper, allowing you to pick colors from anywhere on your screen.

The browser returns an sRGB hex value, which the component then converts into the current editing space before updating value.

The <color-input> element exposes these properties:

value - Current color as a CSS string

const picker = document.querySelector("color-input");
console.log(picker.value); // "oklch(70% 20% 240)"
picker.value = "oklch(80% 15% 180)";

colorspace - Current color space

console.log(picker.colorspace); // "oklch"
picker.colorspace = "hsl";

Supported values:

  • hex
  • srgb
  • srgb-linear
  • hsl
  • hwb
  • lab
  • lch
  • oklab
  • oklch
  • display-p3
  • a98-rgb
  • rec2020
  • prophoto
  • xyz
  • xyz-d50
  • xyz-d65

theme - Visual theme

console.log(picker.theme); // "auto"
picker.theme = "dark"; // "auto", "light", or "dark"

noAlpha - Controls alpha channel visibility

console.log(picker.noAlpha); // false
picker.noAlpha = true; // Hides alpha controls
picker.noAlpha = false; // Shows alpha controls

gamut - Detected gamut (smallest gamut that contains the current color)

console.log(picker.gamut); // "srgb" | "p3" | "rec2020" | "xyz"

contrastColor - Recommended text color for contrast

console.log(picker.contrastColor); // "white" or "black"

Opens the picker popover programmatically:

const picker = document.querySelector("color-input");
picker.show();

show() can also accept a custom anchor element:

picker.show(document.querySelector("#anchor"));

Alias for show() retained for compatibility with earlier versions:

picker.showPicker();

Closes the picker popover:

picker.close();

Sets a custom anchor element for popover positioning:

const customAnchor = document.querySelector("#my-anchor");
picker.setAnchor(customAnchor);

By default, the popover positions relative to the internal trigger button. When possible, the component can use native CSS anchor positioning; otherwise it falls back to manual viewport-aware placement.

<color-input> listens for Popover command events so you can wire it up with declarative popovertarget controls or custom command dispatchers.

  • Buttons with popovertarget automatically send show, hide, or toggle commands that the element consumes.
  • The component accepts either the short (show, hide, toggle) or Popover-specific (show-popover, hide-popover, toggle-popover) command strings.
  • When a command originates from an invoker element, that invoker becomes the new popover anchor via setAnchor().
<button popovertarget="picker" popovertargetaction="toggle">
Toggle color picker
</button>
<color-input id="picker"></color-input>

You can also trigger commands manually:

const cmd = new Event("command", { bubbles: true });
Object.assign(cmd, { command: "show" });
picker.dispatchEvent(cmd);

The <color-input> element dispatches three custom events:

Fired when the color value changes. The event detail contains:

interface ChangeDetail {
value: string; // CSS color string, e.g., "oklch(70% 20% 240)"
colorspace: string; // Current color space, e.g., "oklch"
gamut: string; // Detected gamut: "srgb", "p3", "rec2020", or "xyz"
}
picker.addEventListener("change", (event) => {
const { value, colorspace, gamut } = event.detail;
console.log(`New color: ${value}`);
console.log(`Color space: ${colorspace}`);
console.log(`Gamut: ${gamut}`);
});

Fired when the picker popover opens:

picker.addEventListener("open", () => {
console.log("Picker opened");
});

Fired when the picker popover closes:

picker.addEventListener("close", () => {
console.log("Picker closed");
});

The popover includes a two-dimensional color area. Its model changes with the active colorspace:

  • srgb and hex use an OKHSV-based plane
  • hsl uses saturation × lightness
  • oklch, lch, and wide-gamut RGB-like spaces use a chroma × lightness plane
  • oklab and lab use a centered a × b plane
  • hwb uses whiteness × blackness

Click or drag anywhere inside the area to update the current color. The thumb tracks the current position and the serialized value updates as you move.

Focus the area and use the arrow keys:

  • ←/→ — adjust the X-axis channel in fine steps
  • ↑/↓ — adjust the Y-axis channel in fine steps

Target the area container with ::part(area):

color-input::part(area) {
border-radius: 12px;
aspect-ratio: 16 / 9;
}

For spaces with explicit gamut behavior, the area can render boundary overlays and stretch the mapping so the useful region of the gamut occupies more of the canvas.

The <color-input> element exposes several CSS parts for styling with the ::part() selector:

  • trigger - The button that opens the picker
  • chip - Color swatch inside the trigger button
  • input - Inline text field for direct color entry
  • error - Text with color parsing error message
  • panel - Popover container
  • output - CSS color string display
  • gamut - Gamut badge (srgb/p3/rec2020/xyz)
  • controls - Container for channel sliders and inputs
  • area - Container for area picker

The preview area also exposes two useful pieces of information:

  • a gamut indicator showing the smallest tracked gamut containing the current color
  • contrast ratios against white and black

These are especially useful when the picker is part of a design tool, theming UI, or token editor.