data-color

Display a styled color swatch with hex code for color inputs. Clicking opens the native color picker while maintaining form value.

Overview

The data-color attribute replaces the browser's default color input with a styled display showing a circular color swatch and the hex code. Clicking the display opens the native color picker. The underlying input remains functional for form submission.

<form-field>\n <label for="brand">Brand Color</label>\n <input type="color" id="brand" value="#6366f1" data-color>\n</form-field>

How It Works

Add data-color to any <input type="color">. The init script:

  1. Wraps the input in a .color-wrapper container
  2. Creates a .color-display button containing a .color-swatch span and a .color-hex span
  3. Sets the swatch background color to the current input value
  4. Displays the hex code as text (e.g., #6366f1)
  5. Hides the native color input visually while keeping it in the DOM
  6. Adds a click handler to the display button that opens the native picker
  7. Listens for input events to update the swatch and hex text in real time
  8. Sets data-color-init to prevent double-binding

The native color input remains in the DOM and participates in form submission. The display is a visual layer on top.

Attributes

Attribute Type Description
data-color boolean Enables the color swatch enhancement on a color input.
data-color-init boolean Set automatically to prevent double-binding. Do not set manually.
value string Standard HTML attribute. The hex color value (e.g., #6366f1). Sets the initial swatch color.

DOM Structure

The init script transforms the input into a richer structure. Here is what the enhanced DOM looks like:

<div class="color-wrapper">\n <input type="color" value="#6366f1" data-color data-color-init>\n <button type="button" class="color-display">\n <span class="color-swatch" style="background: #6366f1;"></span>\n <span class="color-hex">#6366f1</span>\n </button>\n</div>

The .color-display button acts as the visual trigger. Clicking it programmatically opens the hidden native color input's picker dialog.

Multiple Colors

Use multiple data-color inputs for theme or palette builders. Each operates independently.

<form-field>\n <label for="bg">Background</label>\n <input type="color" id="bg" value="#ffffff" data-color>\n</form-field>\n\n<form-field>\n <label for="text">Text Color</label>\n <input type="color" id="text" value="#1a1a2e" data-color>\n</form-field>

Color Palette Form

Combine multiple color inputs in a form for a complete palette builder. Each input submits its hex value with the form.

<form class="stacked"> <form-field> <label for="primary">Primary</label> <input type="color" id="primary" value="#6366f1" data-color> </form-field> <form-field> <label for="secondary">Secondary</label> <input type="color" id="secondary" value="#ec4899" data-color> </form-field> <form-field> <label for="accent">Accent</label> <input type="color" id="accent" value="#14b8a6" data-color> </form-field> <button type="submit">Save palette</button> </form>

Live Updates

As the user drags through the native color picker, the swatch background and hex text update in real time via the input event. The change event fires when the picker closes with a final selection.

Event Target Description
input The <input> Fired continuously as the user drags through the picker. Swatch and hex text update in real time.
change The <input> Fired once when the picker closes with a final color selection.
const input = document.querySelector('[data-color]'); input.addEventListener('input', (e) => { console.log('Color changing:', e.target.value); }); input.addEventListener('change', (e) => { console.log('Color selected:', e.target.value); });

Styling

The display button, swatch, and hex text are styled via CSS classes. All styles are gated on [data-color-init] so the native color input renders normally without JavaScript.

/* Color display button */ .color-display { display: inline-flex; align-items: center; gap: var(--size-s); padding: var(--size-xs) var(--size-s); border: 1px solid var(--color-border); border-radius: var(--radius-m); background: var(--color-surface); cursor: pointer; } /* Color swatch circle */ .color-swatch { width: 1.5rem; height: 1.5rem; border-radius: var(--radius-round); border: 1px solid var(--color-border); } /* Hex code text */ .color-hex { font-family: var(--font-mono); font-size: var(--text-sm); }

The swatch uses border-radius: var(--radius-round) for a circular shape. The hex text uses the monospace font stack for consistent character widths.

Dynamic Elements

Inputs added to the DOM after page load are automatically enhanced via a MutationObserver. No manual initialization is needed.

// Dynamically added color inputs are auto-enhanced via MutationObserver const input = document.createElement('input'); input.type = 'color'; input.value = '#ff6600'; input.dataset.color = ''; document.body.appendChild(input); // input is enhanced automatically — no manual init needed

Accessibility

  • The native <input type="color"> remains in the DOM, preserving form submission and validation
  • The display button is focusable and activates the native picker on click or keyboard activation
  • The hex code is visible text, readable by screen readers alongside the label
  • Color value changes are reflected immediately in both the visual swatch and the text hex code
  • Works with <form-field> for label association and validation feedback
  • Without JavaScript, the native color input renders normally (progressive enhancement)