Why your gradient goes muddy in the middle
Tim Knowles (opens in a new tab)12 min read
A muddy gradient is usually two problems at once. The first is the pair of colours. Opposite colours, like blue and yellow, blend straight through the grey centre of the colour wheel. The second is the blend itself. The old default, which browsers still use for hex codes, averages the code numbers, which means the middle comes out too dark. So you can end up with grey, dark, or both. Neighbouring colours and a few extra middle stops fix most of it.
Try out four ways to blend a gradient
73% of this strip asks for colours beyond a normal screen. They’re shown brought gently back into range, keeping their lightness and hue.
At 50%, the old default gives #808080: colour kept 0%, brighter than the darker end.
For the curious: what the four strips are
The old default averages the hex code numbers (gamma-encoded sRGB), which browsers still do for hex colours. How light mixes averages the actual amounts of light (srgb-linear). Even steps blends in Oklab, and keep the colour in OKLCH, the shorter way round the hue circle. Colour kept is the colourfulness (OKLCH chroma) at the marker divided by that of the duller end; darker or brighter compares OKLCH lightness with the darker end.
Every strip is drawn from these calculations rather than left to your browser. Colours a screen can’t show are gamut mapped with the CSS Color 4 method (lower the chroma, keep lightness and hue), not clipped.
What is a gradient doing between your two colours?
You only pick two colours. The gradient has to make up every colour in between, and how it does that is a choice the software makes for you. Different choices give visibly different middles. In Canva or Figma you never see that choice, you only see the result.
Take one pair, pure blue (#0000FF) to pure yellow (#FFFF00), and blend it four ways. Each row shows the colour at the halfway point.
| Blending method | Halfway colour | What you see |
|---|---|---|
| The old default (browsers, with hex codes) | #808080 | Pure grey |
| How light mixes | #BCBCBC | Pale grey |
| Even steps (a newer, perceptual method) | #6CABC7 | Greyish blue |
| Keep the colour | #00BDB0 | Teal |
Nobody chose grey there. In the old default blend, blue to yellow lands on exact grey, not roughly grey. And that one row shows both problems at work. The middle is grey because of where blue and yellow sit on the wheel. But it's darker than the even-steps version because of how the numbers get averaged. The next two sections take those problems one at a time.
Why do opposite colours turn grey in the middle?
The centre of the colour wheel is grey, and a straight blend between opposite colours runs right through it. Picture the wheel as a roundabout with a grey island in the middle. Neighbouring colours are neighbouring exits, so getting from one to the other is a short hop round the edge. Opposite colours sit across the island from each other, and the straight route drives right over it.
On a screen's colour wheel, blue sits opposite yellow, red sits opposite cyan, and purple sits opposite green. Blend any of those pairs the old default way and the halfway point is pure grey: #808080 for blue to yellow and for red to cyan, and an even darker #404040 for purple (#800080) to green (#008000). The designer Erik Kennedy has a name for that patch. He calls it the "grey dead zone".
You'll often read that the newer perceptual blend has no grey middle. For opposite colours, it does. It's just less grey. In my tests, its blue to yellow kept only about a third of its colour at the halfway point, and purple to green kept 7%. The W3C's own example gradients show the same greyish middle. Neighbours are a different story, though. Violet to pink kept 88% or more of its colour in the old default, even-steps and keep-the-colour blends.
So if your gradient joins two colours from opposite sides of the wheel, expect some grey in the middle from most blends.
The middle can come out darker than both ends
Hex numbers aren't proportional to light. They're squashed. The hex value 80 sits halfway between 00 and FF, but it gives off only about 22% of the light, and to get half the light you need BC. The old default blend averages the numbers in your hex codes anyway, so when it lands halfway between two codes, it lands short of halfway in light. In other words, the middle comes out dark.
The squash is on purpose. Our eyes don't judge light evenly: a patch giving off roughly 18% of the light looks about half as bright. So the numbers are spaced to match how we see steps of grey, and that's why black to white looks fine in the old default blend. The trouble starts with colours, because the blend averages the red, green and blue numbers separately.
Red (#FF0000) to green (#00FF00) shows it best. The old default middle is olive, #808000, which is darker than both the red and the green. That wasn't a one-off, either. In 5 of the 8 pairs I tested, the middle came out darker than both ends. Even the W3C, the group that writes the web's colour rules, says the old method gives "overly dark or greyish mixes".
The same averaging is behind a couple of other problems. It's why blue tints drift purple, as shown in Tints, tones and shades. It also gives a white to blue gradient a purplish cast, and Lighter versions of a colour without it turning purple deals with that. And if you're wondering why "even steps" has to be measured by eye rather than by the numbers, that's in Why "same brightness" colours don't look the same.
A side note: blending the way light mixes isn't the gradient fix. Mixing real amounts of light, rather than averaging hex numbers, is physically correct, and Björn Ottosson (opens in a new tab) (he designed the newer perceptual blend) recommends it for blur, resizing and see-through effects. On gradients, though, it looks washed out. Black to white is already a pale grey, #BCBCBC, at the halfway point, because half the light looks well past halfway to white.
Which colour pairs go muddy?
Neighbours are safe. It's the pairs further apart that cause trouble: opposite pairs go grey, and pairs a fair way apart often go dark. These are the eight pairs I tested. "Colour kept" is how much of the duller end's colourfulness survives at the middle of the old default blend.
| Pair | Old default middle | Colour kept | Darker than both ends? | Even-steps middle |
|---|---|---|---|---|
| Blue #0000FF to yellow #FFFF00 | #808080 | 0% | No | #6CABC7 |
| Red #FF0000 to green #00FF00 | #808000 | 49% | Yes | #D0A800 |
| Red #FF0000 to cyan #00FFFF | #808080 | 0% | Yes | #D2A993 |
| Purple #800080 to green #008000 | #404040 | 0% | Yes | #625859 |
| Orange #FF8000 to blue #0066FF | #807380 | 13% | No | #9985AA |
| Hot pink #FF3399 to teal #00B3A6 | #8073A0 | 57% | Yes | #B789A0 |
| Coral #FF6B6B to sky blue #4D96FF | #A681B5 | 51% | Yes | #B68CBA |
| Violet #7B2FF7 to pink #F107A3 | #B61BCD | 97% | No | #B538CE |
So "muddy" can mean greyer, darker or both. Blue to yellow goes grey without dipping below the blue. Hot pink to teal keeps over half its colour but sinks dark. Red to cyan does both. Only the neighbours, violet and pink, come through clean. Keep an eye on that last column too, because it comes in handy when you fix a gradient by hand.
Try out the paths a gradient can take
- 1The old default, middle #808080
- 2Even steps, middle #6CABC7
- 3Keep the colour, middle #00BDB0
- Dashed: beyond a normal screen
How light or dark, along the gradient
The old default dips very slightly below the darker end, by less than you could see. Even steps runs straight.
- The old default
- Even steps
- The darker end’s level
The straight path’s middle keeps 36% of the colour. The path round the wheel keeps 60%, but 73% of it is beyond what a normal screen can show.
For the curious: what the wheel is
It’s the Oklab colour space seen from above: the a and b axes, with lightness flattened out. The scale is stretched to fit each pair, so compare distances within one pair. Even steps is the straight Oklab line, the old default is gamma-encoded sRGB plotted in Oklab, and keep the colour is OKLCH with the shorter hue. The arc is drawn where OKLCH asks to go; the dashed part is outside sRGB, and on screen it is gamut mapped. The chart plots OKLCH lightness.
Keeping the colour means taking a detour
A hue-keeping blend goes round the colour wheel instead of across it, so the middle stays colourful. But on the way it passes through colours you didn't pick. Blue to yellow goes via teal, purple to green goes via a rusty orange, and hot pink to teal goes via periwinkle.
The detour can also run off the road. For opposite pairs, a hue-keeping blend often asks for colours a normal screen can't show. In my blue to yellow test, about three-quarters of the gradient was out of range. The browser then has to pull those colours back in, and it may simply cut the colour back rather than adjust it gently. If you want to know what a screen's range actually is, Why your brand colour looks different on your phone explains it.
So there's no single best method, and the W3C's advice lines up with that. Use even steps when you want the gradient to look evenly spaced, and keep the colour when avoiding grey matters more. In other words, choose by what bothers you more: a duller middle, or a colour you didn't ask for.
Browsers still blend hex the old way
You'd think newer apps and browsers would have fixed all this by now. Some have. But browsers still blend hex the old way, and Figma and Canva don't say what they do.
The web's colour standard, CSS Color 4 (opens in a new tab), makes a newer perceptual blend the default. Then, in section 13.2, it carves out an exception. Hex codes, colour names and the older colour formats must blend the old way, so that existing websites don't suddenly change. In my test, Chrome's engine put #7F7F7F, a plain grey, in the middle of a blue to yellow gradient written in hex. Now, write one colour in a newer format, or name a newer method in the code, and the whole gradient switches. The code for that is in For the curious below.
Photoshop is further along. It offers three gradient methods (opens in a new tab), Perceptual, Linear and Classic, and Perceptual has been its default since late 2021. Illustrator added a Perceptual option in 2025.
Figma and Canva, on the other hand, document nothing about how they blend. Figma's gradient help (opens in a new tab) explains adding and moving stops, and there's no blending setting at all. Users have been asking for one since 2022, and on 15 September 2026 Figma staff replied that there was no update (opens in a new tab). Canva's help (opens in a new tab) lets you use up to 10 colours, each with its own transparency, and it's silent on blending too. You can't look the answer up, but you can find it out yourself in two minutes, and the test in the next section shows you how.
What should you do differently in your next gradient?
Pick your pair with the wheel in mind, and then set the middle colours yourself.
- Pick neighbours, or two shades of one colour. Colours that sit close together on the wheel blend cleanly whatever the app does. It's complementary and triad pairs that grey out or sink dark.
- Add your own middle colours. One well-chosen middle stop removes half to two-thirds of the difference from an even-steps blend. Three or four stops get most pairs close enough that you'd struggle to tell them apart. Blue to yellow, the worst pair, needs about eight, and Canva's 10-colour limit leaves room for that. If you're only adding one stop, take the even-steps middle from the pairs table in this article and put it at 50%.
- Brighten the middle if it sags. If the gradient dips dark, make your middle stop a lighter, cleaner in-between colour, and judge it by eye.
- Test your app once. Draw a rectangle with a gradient from #0000FF to #FFFF00, export it as a full-size PNG, and eyedrop the exact centre. If you get #808080 or #7F7F7F, that's the old default. #BCBCBC means light mixing, #6CABC7 means even steps, and #00BDB0 or #00CFBD means keep the colour. Then repeat it with #FF0000 to #00FF00, where #808000 confirms the old default. In Figma, use sRGB export settings. In Canva, treat the result as a strong hint rather than proof, since exports can be colour-adjusted.
- Fade to transparent with the same colour. Set the faded stop to your solid colour at 0%, not to plain "transparent" or white. Canva's help recommends exactly this. Browsers handle fades well now, but design apps may not.
- Writing CSS? Name the method. A gradient that names its blending method, or uses one colour in a newer format, blends the newer way, and that has worked in Chrome, Edge, Safari and Firefox since June 2024.
Try out adding middle stops to a gradient
Still visibly different
- #0000FF0%
- #1D77E725%
- #6CABC750%
- #B5D79775%
- #FFFF00100%
Canva: add each colour to the gradient in this order. Canva allows up to 10 colours, so 8 in the middle at most.
Figma: click the gradient bar to add a stop, then type each hex code at its position.
For the curious: how close is close?
The middle colours are taken evenly from the even steps blend (Oklab for even steps, OKLCH gamut mapped for keep the colour) and rounded to hex. The demo then blends between them the old way, averaging the hex numbers, and finds the biggest difference from the target anywhere along the strip. Here it is ΔE OK 0.042. Under 0.02, roughly a just-visible difference, counts as hard to tell apart.
Frequently asked questions
Why does my gradient go grey when I fade it to transparent?
Because the transparent end still has a colour, often black or white at 0% opacity, and some apps blend towards that colour on the way out. That's what tints the middle grey. The fix is to make the faded stop the same colour as the solid one, just at 0% opacity, which is exactly what Canva's help recommends. Current web browsers handle fades automatically, but design apps may not, so it's worth setting it yourself.
Can I change how Canva or Figma blends a gradient?
Not as a setting, as of September 2026. Canva lets you pick up to 10 colours and their transparency, and Figma lets you add and move stops, but neither of them documents or offers a choice of blending method. Figma users have been asking for one since 2022. You can get close by hand, though: add a few extra colour stops in the middle, taken from a better-blended version of the same gradient.
What do Perceptual, Linear and Classic mean in Photoshop's gradient settings?
They're three different ways of working out the in-between colours. Perceptual, the default since late 2021, blends using Oklab, a model built around how we see, so the steps look even and the middle stays brighter. Linear blends the way light physically mixes, which keeps vivid pairs bright but turns a black-to-white ramp pale grey early on. Classic is Photoshop's original method. If a gradient looks muddy, try Perceptual first.
Why does blue to yellow make grey, when blue and yellow paint make green?
Because a screen gradient isn't mixing paint. Paint takes light away: blue paint lets through blues and greens, whereas yellow paint lets through yellows, reds and greens, so only green gets past both. A screen blends coloured light instead. Blue and yellow sit opposite each other on its colour wheel, so a straight blend lands on the grey middle. Blend round the wheel, or add a green stop. Where the colour wheel came from explains the split.
For the curious
The old default is blending in gamma-encoded sRGB. "How light mixes" is srgb-linear. "Even steps" is Oklab, which is Björn Ottosson's 2020 perceptual colour space (opens in a new tab), and "keep the colour" is its polar form, OKLCH, which takes the shorter way round the hue circle unless you ask for longer hue.
CSS Color 4 §13.2 makes Oklab the default interpolation space, but legacy colours (hex, named, rgb(), hsl(), hwb()) must blend in sRGB. Write linear-gradient(in oklab, #00f, #ff0), or make one stop an oklch() colour, and the whole gradient switches. color-mix() has no such exception, and Tailwind v4 emits in oklab by default. Clean fades come from premultiplied alpha (§13.4). Out-of-range OKLCH colours should be gamut mapped, but Chromium 141 clipped them in my test. CSS Images 4 (opens in a new tab) even calls its own sRGB example "clearly too dark at the midpoint". If you'd like to see the methods side by side, Adam Argyle's Chrome guide (opens in a new tab) compares them. And banding, the visible stripes you get from too few steps, is a separate problem.
Sources (15)
- W3C, CSS Color Module Level 4 (opens in a new tab), Candidate Recommendation Draft, 13 September 2026, §10.2, §13 and §14
- W3C, CSS Images Module Level 4 (opens in a new tab), Editor's Draft, 18 September 2026, §3.1.1 examples
- W3C, CSS Color Module Level 5 (opens in a new tab), Working Draft, 13 September 2026, §3.1
color-mix() - Björn Ottosson, "How software gets color wrong" (opens in a new tab), 3 December 2020
- Björn Ottosson, "A perceptual color space for image processing" (opens in a new tab), 23 December 2020
- Charles Poynton, "Frequently Asked Questions about Gamma" (opens in a new tab), 1998
- Adobe Help, "Gradient interpolation in Photoshop" (opens in a new tab), updated 24 May 2023
- Adobe Help, "Control perceptual interpolation in gradients" (opens in a new tab) (Illustrator), 28 October 2025
- Canva Help, "Create and use color gradients" (opens in a new tab), retrieved 20 September 2026
- Figma Learn, "Use gradients as a fill or stroke" (opens in a new tab), and Figma Forum, "Support OKLab and OKLCH" (opens in a new tab) (staff reply 15 September 2026), retrieved 20 September 2026
- Tailwind CSS, "background-image: changing interpolation mode" (opens in a new tab), v4 docs
- Adam Argyle, "Access more colors and new spaces" (opens in a new tab), Chrome for Developers, 2 February 2023
- W3C WebDX, web-features
gradient-interpolation(Baseline since 11 June 2024), data retrieved September 2026 - Erik D. Kennedy, "grey dead zone", as summarised by Chris Coyier, CSS-Tricks, 1 March 2021
- My own calculations in Color.js and culori, and test renders in Chromium 141, 20 September 2026
Next: Lighter versions of a colour without it turning purple
Tim Knowles
Websites, marketing strategy and AI training
Tim has worked in marketing since 2000. At Your Marketing Specialist he builds the websites, and colouriser is one of them. He is self-taught, and learns each subject in depth before he advises on it.
Each Article is written from Tim's own research, and every Figure runs on colouriser's own colour maths.
More about Tim (opens in a new tab)