Blurry linear gradient stops in chrome

If I am using a linear gradient with multiple stops like this:

div
{
  border: 1px solid black;
  width: 100px;
  height: 2000px;
  display: inline-block;
  background-image: linear-gradient(to bottom, #383937 0, #001500 35px,
    #ffffff 35px, #b0b0b0 150px, #ffffff 150px, #ffffff 100%);
}

Firefox Problem free.

Chrome The transitions between gradient colors are blurry. I am reusing a position to define a new color, so on position 35, the color goes from #001500 to #ffffff instantly (or at least should). The blurryness between gradient stops increases if the div is taller.

IE There is some blurryness like in chrome, but less extreme. Like in Chrome, the blurryness increases if the div is made higher.

http://jsfiddle.net/cyq7grdr/5/

The gradient in firefox:

gradient in firefox

The gradient in chrome:

gradient in chrome

The gradient in chrome when the div is less tall (1000px instead of 2000px):

enter image description here

edit

It seems like this is fixed in chrome, but introduced in firefox. If anyone can confirm this, I would be happy.


Not a fix to the problem, just a workaround… you can use multiple gradients as multiple backgrounds of a small enough size as to not trigger the problem (< ~300px seems to do it). Combine with background-size and background-position and you get something that is ugly, but works:

background-image:
    linear-gradient(to bottom, #383937 0, #001500 35px, #ffffff 35px, #b0b0b0 150px),
    linear-gradient(to bottom, #963 0, #abc 150px);
background-size:
    100px 150px,
    100px 150px;
background-position:
    0 0,
    0 150px;
background-repeat: no-repeat;

See JSFiddle for demo.


I just had this requirement in a project and solved it this way:

Let's say we want the color change to be 50%.

  • We must place the gradient of the first color from 0% to 51%.
  • And the gradient of the next color from 50% to 100%.

In this way they overlap and create a cut color effect.

.background-overlap {
  background: rgb(97, 0, 189);
  background: linear-gradient(0deg, rgba(46, 49, 49, 1) 0%,  rgba(46, 49, 49, 1) 51%, rgba(232, 232, 232, 1) 50%, rgba(232, 232, 232, 1) 100%);
}

.mydiv {
  height: 90vh;
  width: 100%;
}
<div class="background-overlap mydiv"></div>

I hope it helps.


Functioning workaround for this issue: Just use multiple linear brackgrounds for the background (this is trivially possible with CSS 3) and use transparent background color as an empty placeholder for the other linear background being visible through:

background: 
    linear-gradient(to right, 
      green 10%, 
      yellowgreen 10%, yellowgreen 20%, 
      yellow 20%, yellow 30%, 
      orange 30%, orange 40%, 
      red 40%, red 50%, 
      grey 50%, grey 60%,
      blue 60%, blue 70%,
      transparent 70%
    ),
    linear-gradient(to right,
      green 70%, 
      yellowgreen 70%, yellowgreen 80%, 
      yellow 80%, yellow 90%,
      salmon 90%
    );

To prevent the blurriness issue, all linear gradients in the example above define only 7 explicit gradient end-stops. (Note that the first linear gradient defines an 8th gradient stop, but not an explicit end-stop but just the start stop, as it isn't necessary to explicitly define the start-stop at the beginning or the end-stop at the end of the gradient (0% is automatically used as start-stop and 100% as end-stop), hence the blurriness bug isn't triggered.) The gradients above must use a transparent part to make the gradients below visible and still sharply end the gradient for the block-like visual.

Codepen with bug and workaround demonstration.

Related Chrome issues:

  • https://bugs.chromium.org/p/chromium/issues/detail?id=1103863&q=gradient%20blurry&can=2
  • https://bugs.chromium.org/p/chromium/issues/detail?id=1063769&q=gradient%20blurry&can=2
  • https://bugs.chromium.org/p/chromium/issues/detail?id=887971&q=gradient%20blurry&can=2
  • https://bugs.chromium.org/p/chromium/issues/detail?id=809999&q=gradient%20blurry&can=2

PostCSS plugin for automatically separating gradients with too many stops: https://github.com/strarsis/postcss-blurry-gradient-workaround

Note: The same issue also occurs with gradients as border-image. But border-image doesn't support multiple images or gradients compared to background-image.