Color Picker & WCAG Contrast

Convert between hex, RGB, HSL, OKLCH, HWB. Check WCAG contrast. Extract palettes.

  • Free
  • No signup
  • Files never leave your browser

The color spaces

FormatBest forExample
HexEmbedding in code, sharing#ff8800
RGBMixing with alpha (rgb(r g b / a))rgb(255, 136, 0)
HSLThinking about hue + lightnesshsl(32, 100%, 50%)
OKLCHPerceptually uniform ramps (CSS Color 4)oklch(70.4% 0.18 50)
HWB”Pure color + how much white/black?”hwb(32 0% 0%)

Click any value in the tool to copy it. The active swatch (foreground or background) drives the conversion panel.

WCAG 2.1 contrast thresholds

The Web Content Accessibility Guidelines define four levels:

LevelRatioApplies to
AA Large≥ 3.0:1Text 18pt+ or 14pt+ bold (headings, hero copy)
AA Normal≥ 4.5:1Body text under 18pt — the practical minimum
AAA Large≥ 4.5:1Same large text, stricter target
AAA Normal≥ 7.0:1Body text, strict target for accessibility-first sites

Plain English: aim for 4.5:1 on body text; if you can get 7:1 without sacrificing the design, you should. The tool shows all four badges so you know which audiences your color pair works for.

How “large text” is defined

WCAG says:

  • 18 point regular (≈ 24 CSS pixels at default zoom)
  • 14 point bold (≈ 18.66 CSS pixels at default zoom)

Headings, oversize CTAs, and pull quotes usually qualify. Body paragraphs almost never do, regardless of your base font size.

Palette extraction in detail

The tool uses median-cut clustering, the same algorithm Photoshop uses for indexed-color GIFs:

  1. Decode the image and sample pixels (up to ~20,000 for speed; bigger images are subsampled with a stride).
  2. Skip nearly-transparent pixels (alpha < 16).
  3. Put all sampled pixels into one box bounded by the min/max in each RGB axis.
  4. Find the box with the largest volume × pixel count. Sort its pixels by the longest axis, split at the median.
  5. Repeat until you have 6 boxes.
  6. Average the pixels in each box → palette color. Sort by box population.

Limitations: dominant grey backgrounds tend to swamp the result. Crop tighter to focus the palette on the interesting part.

OKLCH vs HSL — when to use which

  • HSL is hue/saturation/lightness in the sRGB color cube. It is fast, familiar, and works in every browser since IE9 — but it lies. A 10% shift in lightness at hue 240 (blue) looks much darker than the same shift at hue 60 (yellow), because the cube is perceptually warped.
  • OKLCH is the same triplet (lightness/chroma/hue) but in a perceptually uniform space. A 10% lightness shift looks roughly the same regardless of hue. This is why design systems built since 2023 (Tailwind 4, Radix, GitHub Primer) ship OKLCH-based palettes.

The tradeoff: OKLCH needs CSS Color Level 4 support (Safari 16.4+, Chrome 111+, Firefox 113+). If you need to support older browsers, use OKLCH internally but convert to hex/rgb for fallback.

Privacy

Same posture as the rest of the multitool. A static HTML page, a small JavaScript bundle, colorjs.io for parse/convert/contrast math. Everything runs in your browser tab. The Network tab in DevTools confirms it — no requests fire when you pick colors, switch formats, or upload an image. Your colors and images stay on your device.

Frequently asked questions

What is WCAG contrast and which threshold should I aim for?

WCAG 2.1 defines four pass/fail thresholds based on text size: AA Normal (4.5:1) is the practical minimum for body text; AAA Normal (7:1) is the strict target for accessibility; AA Large (3:1) covers headings 18pt+ or 14pt+ bold; AAA Large (4.5:1) is the strict target for the same. Aim for AA Normal on body text. AAA is worth chasing for tools used by people with low vision.

What is OKLCH and why include it?

OKLCH is a perceptually uniform color space added to CSS Color Level 4. A change of 0.01 in the L channel looks like a similar change anywhere in the color space — unlike HSL, where the same numeric shift can mean very different visual differences. Designers use OKLCH for predictable color ramps. The tool clamps out-of-sRGB colors back into the display gamut when outputting hex.

How accurate is the contrast ratio?

The ratio is computed with the WCAG 2.1 relative-luminance formula via colorjs.io. Black on white returns 21:1, identical colors return 1:1, and identical greys return exactly 1.0. Results match the WebAIM contrast checker to two decimal places. APCA (the proposed WCAG 3 replacement) is not yet included — WCAG 2.1 remains the legal requirement in most jurisdictions.

How does the palette extraction work?

You upload any image. The browser decodes it via createImageBitmap, draws it onto a 200×200-max canvas, and reads the raw pixels. A median-cut clustering algorithm partitions the pixels into six color boxes by recursively splitting along the widest RGB axis. The average color of each box is returned, sorted by how many pixels it represents. The image bytes never leave your browser.

My OKLCH output shows an in-gamut color but my CSS shows something different.

OKLCH can describe colors outside the sRGB gamut. The tool clamps to sRGB when generating hex / RGB (because those have no choice), but the OKLCH string itself is unclamped. Older browsers without OKLCH support will fall back to whatever fallback you provide. Modern Safari, Chrome, Firefox handle oklch() natively.

What does AA Large mean — when can I use the looser 3:1 threshold?

WCAG defines "large text" as 18pt (24px) regular weight or 14pt (18.66px) bold or larger. Headings, hero text, and oversize CTAs qualify. Body paragraphs do not, even if your overall font-size is bumped. When in doubt, target the stricter AA Normal threshold.

Does my image leave my browser?

No. Color parsing, conversion, contrast math, and palette extraction all happen in your browser tab. The Network tab in DevTools confirms it — no requests fire when you pick a color, switch formats, or upload an image for palette extraction.

How does the share link work?

Click Copy share link. The current foreground and background hex values are base64-encoded into the URL fragment (after #). The fragment is never sent to a server. Anyone with the link sees the same color pair.

Is this tool really free?

Yes. No signup, no usage limits, no ads.