CSS - Gradients

Easing Linear Gradients

Linear gradients are easy to create in CSS and are extremely useful. As we’ll go through in this article, we can make them visually much smoother by creating them with non-linear gradients. Well, non-linear in the easing sense, anyway!

[…]

In Material Design style guidelines for images, the designers at Google talk about text protection gradients. They call them a scrim. They recommend:

[the] gradient should be long… with the center point about 3/10 towards the darker side of the gradient. This gives the gradient a natural falloff and avoids a sharp edge.

A scrim according to Material Design guidelines

We can’t create exactly that with linear gradients, but we can (and will) create a “low poly” approximation with more color stops.

A scrim with 5 color stops to show the principle

Using only 5 color stops (like in the illustration above) would create some serious banding. Adding more stops makes the gradient a lot smoother. This is exactly what I’ve done in the demo you saw in the first image in this article. Il buono has a 13 color-stop gradient, which makes it blend nicer into the image.

(See the comments in the source link for Sass mixins.)

See also the gradient easing generator by the same author.

Safari bug with gradients that fade to "transparent"

Say you have a gradient in CSS that goes from red to transparent. Easy, right? Like this:

Code language: CSS

.element {
  background: linear-gradient(
    to bottom,
    red, 
    transparent
  );
}

There is a pretty big gotcha here, though.

In Chrome (also Android), Firefox, and Edge, you’d be all good.

But in Safari (also iOS), you’d not be good.

The same test page as before, viewed in both the iOS simulator version of Safari, and the macOS version of Safari. The two rectangles, each with a gradient background colour are different this time. The red in the rectangle on the left fades from red to black, as it fades to transparent, which appears to be a bug. The rectangle on the right fades to transparent while still maintaining the red colour, as expected.
The element on the left in each browser demonstrates the problem.

The problem, the best I understand it, is that transparent is being interpreted (and interpolated) as “transparent black”.

To fix it, you have to set the color as a fully transparent version of that exact color. Like:

Code language: CSS

.element {
  background: linear-gradient(
    to bottom,
    red,
    rgba(255, 0, 0, 0)
  )
}

[…]

Sass can help out, if you are using that:

Code language: Sass

.element {
  background: linear-gradient(
    to bottom,
    #eb8fa9,
    rgba(#eb8fa9, 0);
  )
}