Online Color Picker Guide: Screen Color Picking and Palette Tips
A color picker turns one pixel on your screen into a value you can copy. What decides whether that value survives contact with a real project is something else entirely: which model you use to describe it, what background it sits on, and which value replaces it in dark mode. The same declaration can look like two different colors on a designer's wide-gamut display and on a user's laptop.
This guide skips the click-by-click instructions and covers the part that actually causes rework: the six color models and what each one describes, the four HEX notations browsers accept, why HSL is easier to tune than RGB, how a contrast ratio is calculated step by step, and how to name and theme colors inside a design system. Every figure below is shown with its arithmetic, so you can reproduce it with the tools on this site.
1. The Color Model Family: What Each Notation Actually Describes
Every color model answers the same question — how do I write this color as numbers — but they use completely different coordinate systems, and mixing them up is where most palette bugs start.
RGB is a device coordinate system. It splits color into red, green and blue light channels from 0 to 255. Screens are additive: all three channels at full power give white, all three at zero give black. rgb(255,107,53) is a typical orange. The catch is that RGB has no relationship to human intuition: to make that orange "a bit brighter" you have to change three numbers, and by how much is a matter of trial and error.
HEX is not a separate model — it is RGB written in hexadecimal. Each of the three 0–255 numbers becomes two hex digits, so #FF6B35 and rgb(255,107,53) are the same color. It dominates web and design handoff because it is short, easy to copy, and never needs escaping inside markup.
HSL is the human coordinate system. Hue answers "which color", saturation answers "how vivid", lightness answers "how bright". You can build a full set of shades for one brand color by moving a single number, which is not possible in RGB.
HSV (also called HSB) is a variant of HSL. Hue is defined identically; the difference is what "light" means. In HSL, 100% lightness is pure white. In HSV, 100% value is the fully saturated color. Photoshop's picker uses HSV, so dragging value to the top gives you a vivid color, while setting HSL lightness to 100% in CSS gives you white — one of the most common sources of confusion when design and code are compared side by side.
CMYK is the print coordinate system. It is subtractive: the more ink you stack, the less light bounces back. It describes an ink recipe, and it does not map one-to-one onto emitted light. Vivid cyans and fluorescent oranges that a screen renders happily cannot be printed in four-color process, and certain spot inks cannot be simulated on screen at all.
Lab, OKLab and OKLCH are perceptual coordinate systems. Their goal is that equal numeric steps look like equal visual steps. In sRGB the three channels contribute very unevenly to brightness: at full value, green carries a relative luminance of 0.7152 while blue carries only 0.0722 — nearly a tenfold difference. That is why interpolating or brightening directly in RGB so often drifts the hue. The Lab family flattens that uneven perceptual space mathematically, at the cost of being hard to calculate in your head.
2. HEX Is More Than #RRGGBB
Every HEX notation has precise parsing rules, and a wrong digit never raises an error — it silently becomes a different color. These are the four forms CSS accepts:
| Notation | Meaning | Example | Expands to |
|---|---|---|---|
| #RGB | Three-digit shorthand, each digit doubled | #F53 | #FF5533, i.e. rgb(255,85,51) |
| #RRGGBB | The standard six-digit form | #FF6B35 | rgb(255,107,53) |
| #RGBA | Four-digit shorthand, fourth digit is alpha | #F538 | #FF553388 |
| #RRGGBBAA | Eight-digit form, last two digits are alpha | #FF6B3580 | rgba(255,107,53,0.502) |
Three rules cause most of the damage. First, only six-digit values whose pairs repeat can be shortened. #FF5533 becomes #F53, but #FF6B35 has 6B in the middle, so the shorthand #F63 would mean #FF6633 — a different color. Browsers reject that shorthand, and the whole declaration is dropped.
Second, the last two digits of an eight-digit value are alpha, not extra precision. In #FF6B3580, 80 is 128 in decimal, so opacity is 128 ÷ 255 ≈ 50.2%. Composited over white that value renders as #FFB59A; over black it renders as #80361B. One value, two very different results — the most common reason a sampled color "does not look right" after being pasted into a project.
Third, six- and eight-digit HEX are case-insensitive, so #ff6b35 and #FF6B35 are identical. The real risk is misreading the letter O as a zero or the letter l as a one; that happens far more often than a genuine format error when values are copied by hand or rewritten in bulk. To validate a batch of color values, run them through the regex tester with a pattern such as ^#([0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$.
3. Why HSL Is Easier to Tune, and Its Two Blind Spots
HSL earns its place because one number changes one thing. Drop lightness from 60% to 45% and hue and saturation stay put, so you get the same family of color, just calmer: hsl(16,100%,60%) is #FF6933, 45% gives #E63D00, and 30% gives #992900. A consistent set of brand shades falls out of that arithmetic. Approximating the same set by hand in RGB almost always drifts the hue.
Blind spot one: HSL lightness is not perceived brightness. At lightness 50%, yellow looks far brighter than blue. A scale built from evenly spaced HSL lightness values therefore looks unevenly spaced, with the ends visually compressed.
Blind spot two: HSL interpolation takes the short way around the hue wheel, and that path can cut through unrelated hues. Interpolate from red #FF0000 to blue #0000FF. In RGB the midpoint is #800080, a dark purple with a relative luminance of about 0.0615. In HSL the midpoint is hsl(300,100%,50%), which is #FF00FF, a vivid magenta with a luminance of about 0.2848. The reason is that the short path from 0° to 240° runs backwards through 120° and lands at 300°. The two midpoints differ in luminance by more than four times, and neither matches the intuition of "half red, half blue". Modern browsers can interpolate gradients in OKLab or OKLCH for a more perceptually even result; whether that is available to you depends on the browsers you must support.
4. Which Model to Use, and How It Usually Goes Wrong
| Model | What it describes | Typical use | Common mistake |
|---|---|---|---|
| HEX | RGB in hexadecimal | CSS declarations, design specs, design tokens | Treating the eight-digit form as "more precise" and ignoring that the last pair is alpha |
| RGB / rgba | Device light channels plus alpha | Canvas and graphics APIs, per-channel math | Adding the same amount to all three channels to brighten a color, which shifts the hue |
| HSL | Hue, saturation, lightness | Generating shade scales, tuning a theme color | Using HSL lightness as if it were perceived brightness |
| HSV / HSB | Hue, saturation, value | Photoshop pickers and swatch panels | Confusing HSV value with CSS lightness and copying the number across |
| CMYK | Print ink recipe | Print, packaging, stock and ink specifications | Sending screen values to a printer without specifying a color profile |
| Lab / OKLCH | Perceptually uniform space | Palette algorithms, gradient interpolation, accessible scales | Writing the L value as a percentage into hsl(), since the two syntaxes are unrelated |
The selection rule compresses into three lines: use HEX for static values that go to browsers and design specs; use HSL when you need to generate shades programmatically; and when color has to match across devices and media, settle the color space first — sRGB or Display P3, embedded profile or not — before arguing about values.
5. Three Worked Examples
Example one: one orange, four notations. The picker returns #FF6B35. Split it into FF, 6B and 35, convert to decimal and you get 255, 107 and 53, so the RGB form is rgb(255,107,53). For HSL, the sum of the largest and smallest channels gives (255+53) ÷ 2 ÷ 255 ≈ 60.4% lightness, the hue sits near 16°, and saturation is 100%, so hsl(16,100%,60%). Add alpha for the translucent version and you get #FF6B3580. All four describe the same color; none of them is more accurate than the others.
Example two: can that orange be body text on white? Using the WCAG relative luminance formula, #FF6B35 has a luminance of about 0.3203. Against white (luminance 1) the ratio is (1+0.05) ÷ (0.3203+0.05) ≈ 2.84:1. Against black it is (0.3203+0.05) ÷ (0+0.05) ≈ 7.41:1. The verdict is unambiguous: on white this orange falls far short of the 4.5:1 required for body text and is only usable for large headings or graphics, while on a dark background it passes comfortably. The background, not the color, decides compliance.
Example three: darkening a brand blue until it passes. Suppose #4A90D9 is the primary button color. On white it scores only 3.34:1, so body text on it fails. Hold the hue and reduce lightness: at #3576B8 the ratio reaches 4.74:1, and at #2F6FB0 it reaches 5.22:1. The first just clears the 4.5:1 bar, the second leaves headroom, and both are reasonable design token candidates. You can verify each figure with the color contrast checker.
6. How a Contrast Ratio Is Actually Calculated
A WCAG contrast ratio is not a guess about how different two colors look; it is a reproducible number. Linearize the three sRGB channels, weight them by 0.2126, 0.7152 and 0.0722 to get relative luminance, then compute (L1+0.05) ÷ (L2+0.05) with L1 as the lighter of the two. Because it is a ratio, it maxes out at 21:1 (white on black) and bottoms out at 1:1 (a color on itself).
The thresholds are 4.5:1 for body text and 3:1 for large text (roughly 24px regular or 18.66px bold and up) and for interface graphics. Here is what a few neutral greys actually score:
| Color | Relative luminance | On white | On black | Verdict |
|---|---|---|---|---|
| #000000 | 0.0000 | 21.00:1 | 1.00:1 | The theoretical maximum on white, invisible on black |
| #757575 | 0.1779 | 4.61:1 | 4.56:1 | One of the few greys that passes 4.5:1 on both |
| #777777 | 0.1845 | 4.48:1 | 4.69:1 | Falls just short on white; not valid for body text |
| #949494 | 0.2961 | 3.03:1 | 6.92:1 | Large text, icons and decorative elements only |
This table explains why light grey text is the most common accessibility defect. Move from #757575 one step lighter to #777777 and the ratio falls from 4.61 to 4.48 — visually indistinguishable, yet the compliance verdict flips. The risk is highest for placeholders, captions and disabled states, the text that "looks secondary" and is therefore written in a grey somewhere around 3:1. Pinning that grey at #757575 or darker is easier than fine-tuning near the threshold forever.
7. Design Tokens, Semantic Names and Dark Mode
Writing raw values into components is fastest on day one and unmanageable by month six: the same blue ends up in four notations across a dozen files, and a rebrand means find-and-replace everywhere. The durable pattern is two layers — a raw palette (--blue-500, --orange-600) and semantic tokens on top of it (--color-primary, --color-success, --color-danger, --color-text-muted). Components reference only the semantic layer, so theming and rebranding change a single mapping.
The most common dark mode mistake is inverting colors. Inversion produces complements; the hue has changed, and that is not a dark theme. The correct move is to re-pick values by role, give every semantic token a value in each theme, and verify contrast for each one.
| Semantic token | Light value | Dark value | What copying over does |
|---|---|---|---|
| Primary / link (blue) | #1D4ED8, 6.70:1 on white | #0A84FF, 5.14:1 on #121212 | Reusing #1D4ED8 in dark mode leaves only 2.80:1 |
| Danger (error text) | #B91C1C, 6.47:1 on white | #FF453A, 5.50:1 on #121212 | Dark red smears into a dark grey background at 2.90:1 |
| Divider / overlay | #0000001A over white gives #E5E5E5 | #FFFFFF1F over #121212 gives #2F2F2F | Keeping the same alpha makes dividers look bright and dirty |
The third row deserves a note of its own: a translucent overlay looks different depending on what is underneath, so the alpha itself has to change with the theme. Carrying #0000001A (about 10.2% alpha) from a light theme into a dark one produces a line far brighter than its background — it reads as a smudge rather than a divider.
8. Five Reasons Design and Implementation Disagree
The sampled value matches the spec exactly, yet the page still looks off. These five causes cover almost every case, ordered by how often they occur.
Cause one: different color profiles. The same artwork exported with a Display P3 profile looks more saturated than the sRGB export. Browsers honor the profile when they find it and assume sRGB when they do not, so both the spec value and the code can be correct while the rendered color genuinely differs.
Cause two: the screenshot tool converted the color. When capturing a wide-gamut screen, some tools write the display profile and others convert back to sRGB. That is why sampling a design mockup can return a value that does not match its own annotation — the picker is fine; the screenshot already changed the pixels.
Cause three: lossy compression shifted the color. JPEG introduces noise around high-contrast edges and along gradients, so a sample taken from a JPEG can sit a step or two away from the original. Sample PNG or WebP originals when the value matters; see the image format converter guide for the trade-offs between formats.
Cause four: alpha compositing. A foreground at 50% opacity over a card takes its final color from both layers. If the card background is itself a gradient, the same button is a different color at every position — in that case make the button opaque, or make the background a flat color.
Cause five: the display itself. An uncalibrated screen can be visibly off in white point and gamma, enough to shift the same code by several steps between two machines. That is not a code defect, but it is more than enough to make color review an argument. For brand deliverables, calibrate the display or work from a printed proof.
9. FAQ
- Why does the color I recorded differ from the one the designer gave me?
- First check for the eight-digit form:
#FF6B35and#FF6B3580look different on screen, and the latter composites over white to roughly#FFB59A. If both are six digits, work out whether the value came from a spec annotation or from sampling a screenshot — captures taken on wide-gamut displays are often converted by the capture tool. - Why is HSL lightness not the same as HSV value?
- Because they are defined differently. In HSL, 100% lightness is white and 0% is black, with saturated colors sitting near 50%. In HSV, 100% value is the saturated color itself and lowering it darkens. That is why the brightest, most vivid color in a Photoshop picker translates to roughly 50% lightness in HSL.
- Why does adding 20 to all three RGB channels shift the hue?
- Because the channels contribute unevenly to perceived brightness: green carries 0.7152, red 0.2126 and blue just 0.0722, making green nearly ten times as influential as blue. An equal increase brightens blue far less than green, so the hue drifts toward yellow-green. To brighten while holding the hue, change HSL lightness, or move only L in OKLCH.
- Can dark mode just invert the colors?
- No. Inversion yields complements, so the hues change. Give each semantic token a dark value and verify it:
#1D4ED8scores 6.70:1 on white but only 2.80:1 on#121212, so dark mode needs a lighter blue instead. - Why does a color keep failing 4.5:1 by a hair?
- Because contrast changes fastest in the mid greys.
#757575scores 4.61:1 on white while#777777scores 4.48:1 — a difference you cannot see, but one that flips the verdict. Fixing greys at#757575or darker is more reliable than nudging values around the threshold.
10. Four Common Misconceptions
Misconception one: the same value means the same color. A value only describes numbers; the color space and embedded profile decide the rendering. Identical numbers with and without a Display P3 profile render as two different colors in any browser that performs color management.
Misconception two: a picker reveals the "true" color of a design. A picker reports the numbers of the current frame, and that frame may already have passed through display color management, a screenshot conversion, or scaling interpolation. To reproduce a brand color reliably, get the official value; sample only to cross-check.
Misconception three: more colors look more professional. A primary, an accent and a set of neutral greys usually cover an interface. Every value that never becomes a token is one more thing to miss during a rebrand.
Misconception four: passing contrast equals looking good. 4.5:1 is a readability floor, not an aesthetic target. Palettes that sit exactly on the line often look harsh, while pushing body text past 7:1 and saving light tones for decorative elements is both safer and calmer.
11. Four Practical Habits
- Settle the color space before the values: agree on sRGB as the baseline at kickoff and convert assets on export, so wide-gamut material never sneaks in and produces two renderings of one value.
- Keep color in tokens, not components: components reference semantic names only, the raw palette lives in one place, and a rebrand touches a single mapping.
- Run contrast checks per theme: whenever a foreground color changes, confirm 4.5:1 for body text and 3:1 for large text and icons with the contrast checker, separately for light and dark.
- Name a color the moment you sample it: write it into the palette with a meaningful name instead of leaving a trail of
#FF6B35duplicates. When you need an exact sample from artwork, take it from the original with the color picker rather than from a recompressed screenshot.