Open Source · MIT License

hcg-color-picker

A Google Chrome style color picker — lightweight, dependency-free, alpha support, EyeDropper API.

Live demo →

Installation

Include the stylesheet and script in your HTML file:

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

Or install via npm:

npm install hcg-color-picker
JS — ESM
import hcgColor from 'hcg-color-picker';
import 'hcg-color-picker/hcg-color.css';
JS — CJS
const hcgColor = require('hcg-color-picker');

CDN

Include directly from a CDN — no build step required. Ideal for static pages and quick prototypes.

jsDelivr:

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

unpkg:

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

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


Features

Zero dependencies

Pure vanilla JavaScript — no libraries required.

🎨

Three color modes

Switch between HEX, RGBA, and HSLA input formats.

🔮

Alpha control

Full transparency support, enable or disable per instance.

👁️

EyeDropper API

Pick any color from the screen (Chrome / Edge).

📱

Touch support

Works on mobile and tablet via Pointer Events API.

🔁

Multiple instances

Attach a picker to any number of buttons independently.

⏱️

Debounce option

Built-in change event throttling for expensive handlers.

🔌

Programmatic API

Set color, open/close, enable/disable at runtime.


Basic Usage

Create a button element, attach a picker instance, and listen for color changes:

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

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

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

Options

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

JS
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. Falls back to the element's data-color attribute if not set
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

JS
new hcgColor(el, { color: '#ff0000' });               // 6-digit HEX
new hcgColor(el, { color: '#ff0000ff' });             // 8-digit HEX with alpha
new hcgColor(el, { color: '#f00' });                  // 3-digit shorthand
new hcgColor(el, { color: 'rgb(255, 0, 0)' });         // RGB
new hcgColor(el, { color: 'rgba(255, 0, 0, 0.5)' });   // RGBA
new hcgColor(el, { color: 'hsl(0, 100%, 50%)' });      // HSL
new hcgColor(el, { 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, useful for expensive operations like API calls or database saves.

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

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
JS
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
JS
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
JS
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
JS
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
JS
picker.setAlphaEnabled(false);  // hide alpha slider
picker.setAlphaEnabled(true);   // show alpha slider
.open() / .close() Programmatically open or close the picker
JS
picker.open();
picker.close();

// Check if open
if (picker.isOpen) {
    picker.close();
}
.enable() / .disable() Enable or disable the picker
JS
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
JS
picker.destroy();

All Methods at a Glance

Method Returns Description
.on(event, fn)thisSubscribe to an event
.off(event, fn)thisUnsubscribe a listener
.setColor(color)thisSet the color programmatically, fires change
.getColor()objectReturns color object with all formats
.setAlphaEnabled(bool)thisShow or hide the alpha slider at runtime
.open()thisOpen the picker (no effect if disabled)
.close()thisClose the picker
.isOpenbooleanGetter — true if this picker is currently open
.enable()thisRe-enable a disabled picker
.disable()thisDisable the picker — blocks opening on click
.destroy()voidRemove instance, clean up all listeners

Events

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

EventCallback dataDescription
changecolors, sourceFired every time the color changes
openhex stringFired when the picker opens
closehex stringFired when the picker closes
change Fires on every color update — includes all formats
JS
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
JS
picker.on('open', hex => console.log('Opened with:', hex));
close Fires when the picker closes — receives final hex color
JS
picker.on('close', hex => console.log('Closed with:', hex));

Color Formats

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

JS
{
    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.

JS
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 npm package — no setup required beyond installing and importing.

Installation

npm install hcg-color-picker-react

Import

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

Basic Usage

JSX
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>
            <ColorPicker color="#ff0000" onChange={handleChange} />
            <ColorPicker color="#0000ff" alpha={false} onChange={handleChange} />
            <ColorPicker color="#9c27b0" debounce={200} onChange={handleChange} />
            <ColorPicker color="#00ff00" disabled={true} />
        </div>
    );
}

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


Browser Support

FeatureSupport
Color picker UIAll modern browsers
Touch eventsiOS Safari, Android Chrome
EyeDropper APIChrome 95+, Edge 95+ (not Firefox / Safari)