HTML & CSS Tip of the Week

Single-colour gradients

Published on


Gradients are generally for going from one colour to another, so the idea of a single-colour gradient might seem a bit useless, but there are a few good use cases for them.

Making Text Readable with Gradient Overlays

I used to use pseudo-elements to create overlays on top of images, in order to help keep my text legible, and as much as I love pseudo-elements, it was a bit of a waste of time.

The Basic Technique

The key is using a single-color linear gradient with an alpha value to create a darkening effect:

.overlayed-background-image {
  background-image: 
    linear-gradient(hsl(0 0 0 / .5)),
    url('/assets/a-background.webp');;
}

When layering background images like this, the order of the images follows the order you declare them in, so in the example above, my linear gradient is on top of the image.

Better browser support

While single-color gradient stops like the example above work great in modern browsers, they’re a relatively new feature.

For broader browser support, you can add 0 0 to the end, which looks strange, but it creates two colour stops, which is all those older browsers need.

.overlayed-background-image {
  background-image: 
    linear-gradient(hsl(0 0 0 / .5) 0 0),
    url('/assets/a-background.webp');;
}

In the future, we will be able to use the more purpose-built image(), which makes things a bit easier, but currently no browser supports it.

.text-overlay {
  background-image: 
    image(hsl(0 0% 0% / .5)),
    url('/assets/a-background.webp');
}

Creating Gradient Borders

Gradient borders are having a major moment in modern web design, and while we do have border-image, we can’t use it if we want to maintain a border-radius.

Once again, single-color gradients come to the rescue.

The setup

The secret to gradient borders is using multiple background layers, and controlling the parts of the box model they are clipped to.

To start, you’ll need a transparent border, which will be how thick your gradient border is.

.gradient-border {
  border: 10px solid transparent;
}

Next, we need to declare two different background images, one which is a solid color, and the second which is the actual gradient.

The trick is to have the solid colour stop only fill up the padding box, while the actual gradient goes to the edge of the border box.

.gradient-border {
  border: 10px solid transparent;
  background: 
    linear-gradient(white) padding-box,
    conic-gradient(red, blue, red) border-box;
}

Above, I’m accomplishing this using the background shorthand. I’m not a huge fan of shorthands, but this one is handy because we’re declaring both the background-origin and background-clip for the padding-box and border-box, which gives us the desired result.