Skip to main content

Color Mixer: How to Blend Two Colors by Ratio and Space

A practical guide to using a color mixer: blend two HEX colors by ratio, see why RGB, HSL, and LAB midpoints differ, and pick the right blend for design work.

Published By 李雷
#color #design #css #gradient #tools

Color Mixer: How to Blend Two Colors by Ratio and Space

A color mixer answers one specific question that a color picker never does: you already have two colors, so what comes out when you blend them? Not a harmonized palette, not a single swatch — the exact value sitting somewhere between point A and point B, at any ratio you choose. That sounds trivial until you try it and realize the same two colors produce three different "middles" depending on which color space you mix in.

This guide walks through how blending actually works, why the math matters, and when each mode earns its place. You can follow along in the Color Mixer, which does all of this in the browser.

Two colors in, one result out

Start with the simplest case: two HEX values and a 50/50 split. Drop in blue #2563EB and orange #F97316, pull the ratio slider to the middle, and read the result. The mixer outputs HEX, RGB, HSL, and LAB at once, so you copy whichever format your codebase or design tool wants.

The ratio is where most of the day-to-day value lives. A 50% blend is the obvious midpoint, but 25% and 75% give you tertiary tints — the in-between accents you reach for when a single hue feels too flat. Quick presets at 25 / 50 / 75 make those one-click, and the slider covers everything in between when you need, say, a 30% lean toward the brighter color.

The same two colors, three different middles

Here is the part people miss. Mixing is not one operation — it depends on the space you average the numbers in. Take pure blue #0000FF and pure yellow #FFFF00 at exactly 50%:

  • RGB averages the red, green, and blue channels straight: (0,0,255) and (255,255,0) average to (128,128,128) — wait, that's #808080, a flat gray. For this particular pair the muddy midpoint is dramatic. (Blue plus yellow in RGB lands on khaki-grays, never the green you'd expect from a paint set.)
  • HSL rotates the hue between the two colors instead of averaging channels, so the midpoint stays saturated and reads as a real, vivid color rather than a wash.
  • LAB is perceptually uniform: equal numeric steps look equally spaced to the human eye, which is why it's the color-science standard.

That gap is not a rounding quirk. RGB is fast and matches what CSS, Canvas, and WebGL do by default, but the arithmetic average of two saturated colors pulls toward gray. HSL keeps saturation. LAB keeps perceived evenness. Pick the wrong one and your "blend" looks dead.

Why the LAB midpoint looks darker than RGB

The cleanest demonstration is black-and-white. Mix #000000 and #FFFFFF at 50%:

  • RGB gives #808080 — the arithmetic middle. But sRGB is gamma-encoded, so the value 128 actually emits about 21.6% luminance, which your eye reads as more than halfway between black and white.
  • LAB gives roughly #777777 — CIE L\*=50, which encodes about 18.4% luminance. Numerically darker, but it's the gray your eye genuinely perceives as the true middle.

Per the CIE L\*a\b\ model, the lightness axis is built around human perception rather than raw signal, which is exactly why design systems lean on it for tint ramps. When you build a 5, 9, or 11-step gradient — Tailwind's slate-50 through slate-950, or Material's 50 to 900 — generating it in LAB keeps each visible step the same size. Do the same ramp in RGB and the mid-steps crowd together while the ends stretch out.

A worked example you can copy

Say you're merging two brand accents during a rebrand: old pink #DB2777 moving to new purple #7C3AED, and the PM wants a defensible transitional shade for the in-between sprint.

  • Endpoints: #DB2777 and #7C3AED
  • Ratio: 50%
  • Space: LAB (so the midpoint reads as the true perceptual middle, not a channel average)

The mixer returns a single blended HEX plus its RGB and HSL forms. You paste that one value into the accent token and ship it, instead of arguing over three near-identical purples in Slack. Switch the same blend to RGB and you'll see a slightly different, slightly grayer value — a useful side-by-side for understanding why the LAB result feels more correct.

When I actually reach for each mode

I keep the default on RGB only when I need the result to match a CSS gradient or a Canvas globalCompositeOperation exactly, because that's the math the browser runs. The moment I'm mixing two saturated hues — two brand colors, a warm and a cool accent — I switch to HSL or LAB before I even look at the midpoint, because I already know RGB will hand me a gray I don't want. For any production token ramp, it's LAB every time: I'd rather the nine steps in my palette look evenly spaced on screen than be evenly spaced in a number space my eye doesn't share. The toggle takes a second, and the difference between a flat ramp and a clean one is right there in the swatches.

What a mixer is not

A blend on screen is an sRGB value, and screens and physical pigments live in different gamuts. The HEX you mix here renders correctly on a monitor, but the printed equivalent depends on the ink set, paper, and ICC profile — treat the digital result as a target and let a print workflow convert it. Real paint also mixes subtractively (closer to LAB / Kubelka–Munk math than RGB), so LAB mode feels nearer to physical pigment behavior, though it's still no substitute for a real swatch.

For full ramps and CSS-ready output, once you've nailed your two endpoints you can take them straight into the Gradient Generator to fine-tune stops and export a linear-gradient(). The mixer settles the two endpoints; the gradient tool handles everything between them at scale.

Blending two colors is a thirty-second task that quietly carries a lot of color science. Get the space right, read the ratio, copy the HEX — and your "middle" finally looks like the middle.


Made by Toolora · Updated 2026-06-13