Mitigating CSS gradient banding
While working on a design that included a gradient, I noticed banding when the gradient was rendered by the browser.
The following image shows the issue and in comparison the technique I used to workaround the problem.
{{< figure src="/images/2016-09-16-css-banding.png" title="CSS banding" >}}
- Augmented contrast of stepped CSS gradient.
- Stepped CSS gradient (the result we actually want).
- Naive CSS gradient
- Augmented contrast of the CSS gradient (to highlight the banding issue).
What are we seeing here? Simply put, the browser cannot render a gradient properly. As I cannot fix the browsers (seen into Safari, Chrome and Firefox), I tried to find a workaround.
The workaround I found is what I call "stepped gradient". Basically, instead of having one gradient from color A to B, I to a serie of gradients from A to A1, then A1 to A2… until An to B. Where Ax is closer to B each time.
The SASS code to achieve this is below.
$g: transparent;
$steps: 10;
@for $i from 1 to $steps {
$g: append($g, fade-out($bg-color, 1 / $i) percentage($i / $steps), comma);
$g: append($g, fade-out($bg-color, 1 / $i) percentage(($i + 0.6) / $steps), comma);
}
$g: append($g, $bg-color);
background: linear-gradient(to bottom, $g);