Google Chrome Style JavaScript Color Picker


Create modern color selection interfaces with this lightweight JavaScript color picker inspired by the Google Chrome color picker UI. The library supports HEX, RGBA, HSLA, and alpha transparency color formats for flexible color selection and conversion.

Built-in EyeDropper API support allows users to pick colors directly from anywhere on the screen in supported browsers. The color picker is fully touch-friendly, keyboard accessible, and optimized for both desktop and mobile devices.

Multiple independent picker instances can share a single reusable UI component, helping reduce memory usage and improve performance. Advanced features include live color preview, event listeners, programmatic API methods, and runtime control for opening, closing, enabling, disabling, and updating colors dynamically.

Code links:

Live Demo

Explore interactive color picker demos including default mode, alpha-disabled mode, and disabled state examples. Click any color button to open the picker and preview color selection in real time.

Default:

No alpha:

Disabled:


Color Picker Preview

chrome style color picker chrome style color picker without alpha

Features

Lightweight Chrome-style color picker with HEX, RGBA, HSLA, alpha control, EyeDropper API support, touch support, and multiple instances.

Lightweight & Dependency Free

Built using pure vanilla JavaScript with no external libraries or frameworks required.

🎨

Chrome Inspired UI

Modern popup design similar to the built-in Google Chrome color picker experience.

🌗

Alpha Transparency Control

Enable or disable opacity selection with a built-in alpha slider.

🪄

Multiple Picker Instances

Attach independent color pickers to multiple buttons or elements while sharing a single optimized UI component.

🔬

EyeDropper API Support

Pick colors directly from anywhere on the screen in supported browsers.

📱

Mobile & Touch Friendly

Works smoothly on mobile phones, tablets, and touch-enabled devices.

🕐

Debounce Support

Built-in change event throttling- delay callbacks until the user stops dragging to avoid expensive operations on every frame.

📡

Event System

Subscribe and unsubscribe to change, open, and close events using simple callback methods.

🎯

Multiple Color Formats

Supports:

  • HEX
  • HEXA
  • RGB
  • RGBA
  • HSL
  • HSLA
⚙️

Programmatic API

Control the picker using JavaScript methods like:

  • setColor()
  • getColor()
  • open()
  • close()
  • enable()
  • disable()
  • destroy()

Installation

Include the stylesheet and script in your HTML file:

HTML
<link rel="stylesheet" href="hcg-color.css">
<script src="hcg-color.js"></script>

NPM Usage

Install the package via npm for use in module bundler projects such as Webpack, Vite, or Rollup.

Install:

NPM
npm install hcg-color-picker

ESM import:

JS - ESM
import hcgColor from 'hcg-color-picker';
import 'hcg-color-picker/hcg-color.css';

CommonJS require:

JS - CJS
const hcgColor = require('hcg-color-picker');

CDN

Include the stylesheet and script directly from a CDN, no installation or build step required. Ideal for quick prototypes and static HTML pages.

jsDelivr:

HTML
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/hcg-color-picker@2.0.0/hcg-color.css">
<script src="https://cdn.jsdelivr.net/npm/hcg-color-picker@2.0.0/index.umd.js"></script>

unpkg:

HTML
<link rel="stylesheet" href="https://unpkg.com/hcg-color-picker@2.0.0/hcg-color.css">
<script src="https://unpkg.com/hcg-color-picker@2.0.0/index.umd.js"></script>

After the script loads, hcgColor is available as a global variable.

Basic Usage

Create a new picker instance and attach it to a button or HTML element using pure vanilla JavaScript.

HTML
<button id="color-btn">Pick Color</button>

<script>
    const picker = new hcgColor(
        document.getElementById('color-btn'),
        { color: '#ff0000' }
    );

    picker.on('change', function (colors, source) {
        console.log(colors.hex);   // "#ff0000"
        console.log(colors.rgba);  // "rgba(255, 0, 0, 1)"
        console.log(colors.hsla);  // "hsla(0, 100%, 50%, 1)"

        console.log(source); // "drag" | "input" | "api" | "eyedropper"
    });
</script>

Options

Pass an options object as the second argument to the constructor:

JavaScript
const picker = new hcgColor(element, {
    color:    '#ff0000',
    onChange: colors => console.log(colors.hex),
    onOpen:   hex => console.log('opened', hex),
    onClose:  hex => console.log('closed', hex),
    alpha:    true,
    debounce: 150,
    disabled: false,
});
Option Type Default Description
color string data-color or #ff0000 Initial color - accepts HEX, RGB, HSL formats
onChange function - Shorthand change callback, same as .on('change')
onOpen function - Shorthand open callback, same as .on('open')
onClose function - Shorthand close callback, same as .on('close')
alpha boolean true Set to false to disable the alpha slider
debounce number 0 ms to debounce the change event during drag (0=off)
disabled boolean false Start in disabled state - also reads the element's disabled attribute

Color Format Examples

JavaScript
new hcgColor(element, { color: '#ff0000' });                // 6-digit HEX
new hcgColor(element, { color: '#ff0000ff' });              // 8-digit HEX with alpha
new hcgColor(element, { color: '#f00' });                   // 3-digit shorthand
new hcgColor(element, { color: 'rgb(255, 0, 0)' });         // RGB
new hcgColor(element, { color: 'rgba(255, 0, 0, 0.5)' });   // RGBA
new hcgColor(element, { color: 'hsl(0, 100%, 50%)' });      // HSL
new hcgColor(element, { color: 'hsla(0, 100%, 50%, 1)' });  // HSLA

Debounce

By default the change event fires on every pointer move during drag, up to 60 times per second. The debounce option delays the event until the user pauses or stops dragging, which is useful for expensive operations like API calls, saving to a database, or heavy re-renders.

JavaScript
const picker = new hcgColor(btn, {
    color:    '#ff0000',
    debounce: 200,
    onChange: (colors) => {
        console.log(colors.hex); // fires 200ms after drag stops
    }
});

Without debounce the change event fires continuously during drag. With debounce: 200 the event waits 200ms after the last movement before firing. Set to 0 to disable debouncing entirely.

Live comparison, drag the sliders and watch the counters:

No Debounce debounce: 0:

#e91e63
onChange fired:
0
times

With Debounce debounce: 200:

#2196f3
onChange fired:
0
times

Instance Methods

.on(event, callback) Subscribe to an event

JavaScript
picker.on('change', function (colors, source) {
    console.log(colors.hex);   // "#ff0000"
    console.log(colors.hexa);  // "#ff0000ff"
    console.log(colors.rgb);   // "rgb(255, 0, 0)"
    console.log(colors.rgba);  // "rgba(255, 0, 0, 1)"
    console.log(colors.hsl);   // "hsl(0, 100%, 50%)"
    console.log(colors.hsla);  // "hsla(0, 100%, 50%, 1)"

    console.log(source); // "drag" | "input" | "api" | "eyedropper"
});

.off(event, callback) Unsubscribe a specific listener

JavaScript
function onChange(colors) { console.log(colors.hex); }

picker.on('change', onChange);
picker.off('change', onChange);

.setColor(color) Programmatically set the color, fires the change event

JavaScript
picker.setColor('#00ff00');
picker.setColor('rgb(0, 255, 0)');
picker.setColor('hsl(120, 100%, 50%)');

.getColor() Returns the current color as an object with all formats

JavaScript
const colors = picker.getColor();
// {
//     hex:  "#ff0000",
//     hexa: "#ff0000ff",
//     rgb:  "rgb(255, 0, 0)",
//     rgba: "rgba(255, 0, 0, 1)",
//     hsl:  "hsl(0, 100%, 50%)",
//     hsla: "hsla(0, 100%, 50%, 1)"
// }

picker.getColor().hex   // "#ff0000"
picker.getColor().rgba  // "rgba(255, 0, 0, 1)"

.setAlphaEnabled(boolean) Show or hide the alpha slider at runtime

JavaScript
picker.setAlphaEnabled(false);  // hide alpha slider
picker.setAlphaEnabled(true);   // show alpha slider

.open() / .close() Programmatically open or close the picker

JavaScript
picker.open();
picker.close();

// Check if open
if (picker.isOpen) {
    picker.close();
}

.enable() / .disable() Enable or disable the picker

JavaScript
picker.disable();  // prevents the picker from opening on click
picker.enable();   // re-enables the picker

.destroy() Remove the instance and clean up all event listeners

JavaScript
picker.destroy();

All Methods at a Glance

Method Returns Description
.on(event, fn) this Subscribe to an event
.off(event, fn) this Unsubscribe a listener
.setColor(color) this Set the color programmatically, fires change
.getColor() object Returns color object with all formats
.setAlphaEnabled(bool) this Show or hide the alpha slider at runtime
.open() this Open the picker (no effect if disabled)
.close() this Close the picker
.isOpen boolean Getter - true if this picker is currently open
.enable() this Re-enable a disabled picker
.disable() this Disable the picker - blocks opening on click
.destroy() void Remove instance, clean up all listeners

Events

Subscribe to events with .on() and unsubscribe with .off().

Event Callback data Description
change (colors, source) Fired every time the color changes
open hex string Fired when the picker opens
close hex string Fired when the picker closes

change Fires on every color update - includes all formats

JavaScript
picker.on('change', (colors, source) => {
    console.log(colors.hex);   // "#ff0000"
    console.log(colors.hexa);  // "#ff0000ff"
    console.log(colors.rgb);   // "rgb(255, 0, 0)"
    console.log(colors.rgba);  // "rgba(255, 0, 0, 1)"
    console.log(colors.hsl);   // "hsl(0, 100%, 50%)"
    console.log(colors.hsla);  // "hsla(0, 100%, 50%, 1)"

    console.log(source);      // "drag" | "input" | "api" | "eyedropper"
});

open Fires when the picker opens - receives current hex color

JavaScript
picker.on('open', hex => console.log('Opened with:', hex));

close Fires when the picker closes - receives final hex color

JavaScript
picker.on('close', hex => console.log('Closed with:', hex));

Color Formats

The colors object returned by onChange and .getColor():

JavaScript
{
    hex:  "#ff0000",       // 6-digit HEX - no alpha
    hexa: "#ff0000ff",     // 8-digit HEX - with alpha
    rgb:  "rgb(255, 0, 0)",
    rgba: "rgba(255, 0, 0, 1)",
    hsl:  "hsl(0, 100%, 50%)",
    hsla: "hsla(0, 100%, 50%, 1)"
}

Multiple Instances

Each instance is fully independent - they share one picker UI but each stores its own color state.

JavaScript
const picker1 = new hcgColor(document.getElementById('btn1'), { color: '#f44336' });
const picker2 = new hcgColor(document.getElementById('btn2'), { color: '#2196f3' });
const picker3 = new hcgColor(document.getElementById('btn3'), { color: '#4caf50', alpha: false });

picker1.on('change', colors => console.log('Picker 1:', colors.hex));
picker2.on('change', colors => console.log('Picker 2:', colors.hex));

React Package

A dedicated React component is available as a separate package for React projects. The component supports all the same options as the vanilla JavaScript version including alpha control, debounce, disabled state, and programmatic API via ref.

Install:

NPM
npm install hcg-color-picker-react

Import:

JavaScript
import ColorPicker from 'hcg-color-picker-react';
import 'hcg-color-picker-react/ColorPicker.css';

Basic usage:

JavaScript
function App() {
    function handleChange(colors, source) {
        console.log(colors.hex);   // "#ff0000"
        console.log(colors.rgba);  // "rgba(255, 0, 0, 1)"
        console.log(source);       // "drag" | "input" | "api" | "eyedropper"
    }

    return (
        <div>
            {/* Basic */}
            <ColorPicker color="#ff0000" onChange={handleChange} />

            {/* No alpha */}
            <ColorPicker color="#0000ff" alpha={false} onChange={handleChange} />

            {/* Debounced */}
            <ColorPicker color="#9c27b0" debounce={200} onChange={handleChange} />

            {/* Disabled */}
            <ColorPicker color="#00ff00" disabled={true} />
        </div>
    );
}

Full documentation and examples: hcg-color-picker-react on npm

Browser Support

Feature Support
Color picker UI All modern browsers
Touch events iOS Safari, Android Chrome
EyeDropper API Chrome 95+, Edge 95+ (not Firefox / Safari)