frontend engineering

Build a Color Picker Component

Color pickers appear in design tools (Figma, Sketch), CMS apps, and customization UIs. The interview tests whether you understand color spaces, gesture handling, and the polish that makes a picker feel professional.

Functional requirements

  • Color spectrum (hue or saturation/value): the centerpiece — a 2D area for saturation and value plus a separate hue control. Interviewers watch how you map pointer coordinates onto color values and keep the spectrum and inputs in sync as either one changes.
  • Hex / RGB / HSL input fields: let users type a value directly and see it reflected everywhere. The common probe is what happens on a partial or invalid entry — validate on blur rather than on every keystroke so a half-typed hex like #F doesn’t blow away the current color.
  • Alpha slider (transparency): controls opacity from 0 to 1, rendered over a checkered background so the transparency is visible. Be ready to say how alpha rides along in the output format, e.g. rgba() or an 8-digit hex.
  • Eyedropper (modern browsers): samples any pixel on screen via the native EyeDropper API. Interviewers want to hear you feature-detect and hide the button entirely when the API is absent, rather than showing a control that does nothing.
  • Color presets / swatches: a fixed palette of common or brand colors for one-click selection. Talk about configuring the set per app context and making a preset click update every input and the spectrum position, not just the preview.
  • Recently used colors: a short history of picks, persisted so it survives a reload. The interesting part is dedup and eviction — keep the last N distinct colors, most-recent first, and move a re-picked color back to the front instead of adding a duplicate.

Color spaces

  • HSL/HSV: human-friendly (hue, saturation, lightness/value)
  • RGB: computer-friendly (0–255 per channel)
  • Hex: CSS standard (#FF5733)
  • OKLCH: perceptually uniform; modern (CSS Color 4)

Most pickers use HSV/HSL for the visual interface and offer hex/RGB as input options.

The classic picker UI

Standard layout:

  • Saturation/value square (large 2D area)
  • Hue slider (vertical)
  • Optional: alpha slider
  • Hex input + RGB inputs
  • Color preview swatch

Saturation/value square

The interactive 2D area:

  • X axis: saturation (0% → 100%)
  • Y axis: value (100% → 0% top-to-bottom)
  • Background: gradient combining both
  • Cursor: small circle showing current position

Pointer event handling: mousedown sets pointer; mousemove updates position; mouseup releases.

Hue slider

Vertical (or horizontal) slider with hue gradient (red → yellow → green → cyan → blue → magenta → red).

Same pointer-event handling as saturation/value square.

Conversions

Convert between formats as user adjusts. Common formulas:

  • HSL ↔ RGB: math is well-known
  • RGB ↔ Hex: trivial conversion
  • OKLCH ↔ RGB: more complex; use a library (culori, color.js)

Library: colord for lightweight conversions; culori for OKLCH and color science.

Eyedropper API

Modern browsers (Chromium 95+):

const eyeDropper = new EyeDropper();
const result = await eyeDropper.open();
console.log(result.sRGBHex);

Lets user pick a pixel color from anywhere on screen. Beautiful UX. Falls back gracefully when not supported.

Recent colors

Track colors the user has selected:

  • Last 10 distinct colors
  • Stored in local storage
  • One-click reuse

Color presets

Predefined swatch palette (tailored per app context). Common: brand colors, theme colors.

Accessibility

  • Each input is keyboard-accessible
  • aria-label for the picker overall
  • aria-valuetext announces current color in a readable form (“red 200 saturation 80”)
  • Contrast checker integration: warn if text on this color fails WCAG

Mobile considerations

  • Touch areas large enough (min 44×44 pt)
  • Two-finger drag for fine adjustment
  • Floating preview to avoid finger covering target

Common mistakes

  • Inputs that go out of sync (typing in Hex does not update RGB)
  • Performance: re-render on every pointer move at 60 FPS without throttle
  • No accessibility — only mouse-driven
  • Eyedropper API not used where supported

Library options

  • react-color: popular, multiple picker styles
  • react-colorful: tiny (2KB), modern
  • chrome-style-picker: matches Chrome devtools

Frequently Asked Questions

Should I support OKLCH?

For modern design tools, yes — perceptual uniformity matters. For typical apps, HSL/HSV is sufficient.

How do I handle the alpha channel?

Separate slider for alpha. Show a checkered background behind the swatch to visualize transparency.

Can I use the native HTML color input?

For simple use cases, yes — <input type="color"> works. No customization, but accessible by default.

newsletter

What's actually being asked right now

Interview patterns & comp trends, straight to your inbox.

No spam. Unsubscribe anytime.

newsletter

What's actually being asked right now

Interview patterns & comp trends, straight to your inbox.

No spam. Unsubscribe anytime.

1972 Soviet postage stamp commemorating the Mars 2 probe

worth a read

Mars For The Rest of Us — a weekly-or-more deep dive on the technical side of Mars exploration: rocket propulsion, microbiology, mission architecture, and everything in between. Written by Maciej Ceglowski.

Read it on Substack →
Scroll to Top