Create a gradient border in CSS

Published: · Updated: · Reading time: 7 min

To show gradients for a border with CSS you can use the border-image property. It allows setting gradient values in the same way as the background-image property.

Besides the border-image property, you should specify additional properties to actually show border gradient.

  • border-width
  • border-style
  • border-image-source
  • border-image-slice

We can combine these properties into a shorthand syntax border-width with border-style into border and border-image-source with border-image-slice into border-image.

.gradient-border {
  border: 5px solid;
  border-image: linear-gradient(45deg, purple, orange) 1;
}

Result:

Hello World!

Now you have a nice looking gradient border. And you can use all types of gradients: linear-gradient, radial-gradient and conic-gradient.

However, there’s a drawback to this approach. You cannot use border-radius property, as it is not supported with the border-image property. But there are a few workarounds.

Pseudo element

Positioning trick

For this approach, we need to add a gradient as a background-image for the pseudo-element. Additionally, we need to set its position to absolute and set a negative margin, that will represent the border width. Give it a negative z-index to make it below the main element. And finally, make it inherit border-radius from the main element.

For the initial element, we need to set the required border-radius. Set background color, to match the body background. Optionally we give it a margin to make it within the boundaries of the container because pseudo-element has a negative margin.

.gradient-border-pseudo {
  position: relative;
  padding: 10px 20px;
  background: #fff;
  margin: 5px;
  border-radius: 5px;
}

.gradient-border-pseudo::after {
  content: "";
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  z-index: -1;
  margin: -5px;
  border-radius: inherit;
  background-image: linear-gradient(45deg, purple, orange);
}

Result:

Hello World!

Masking trick

For this solution, we’ll also use the pseudo-element, but instead of positioning it with z-index, we will use the mask property to clip the background.

The mask CSS shorthand property hides an element (partially or fully) by masking or clipping the image at specific points.

- MDN

While the mask property may lack full support, you can use this approach for the gradient border.

We’ll set the element’s background as a gradient. And then using mask property we’ll specify two more gradient backgrounds (same color as body). The first one will mask (cover) the area within the padding boundaries, and the second one will mask (cover) the area all the way up to the border.

Additionally, we need to set the mask-composite property to exclude the top layer from the bottom in order to see the border.

.gradient-border-mask {
  position: relative;
  padding: 15px 20px;
}

.gradient-border-mask::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  border-radius: 50px; 
  border: 5px solid transparent;
  background: linear-gradient(45deg,purple,orange) border-box;
  -webkit-mask:
    linear-gradient(#fff 0 0) padding-box, 
    linear-gradient(#fff 0 0);
  -webkit-mask-composite: destination-out;
  mask-composite: exclude;
}

Result:

Hello World!

Background clip

To avoid additional styles for pseudo-element you can use the background-image property in combination with background-clip property.

The background-clip CSS property sets whether an element’s background extends underneath its border box, padding box, or content box.

- MDN

Essentially we’re going to clip the background in the similar way we did with the mask property.

First, we’ll need to pass two gradients values for the background-image. One will represent the background of the element with the according color, and the second one will represent the border with gradient.

For each of the gradients, we’ll specify the background-clip property.

For the first one, the value will be padding-box, so the background will extend up until the border.

For the second one, the value will be border-box, which means that the background will extend to the outside edge of the border.

Finally we need to specify a transparent border color and border-radius, and it’s done.

.gradient-border-bg {
  background: linear-gradient(#fff, #fff) padding-box,
              linear-gradient(45deg, slateblue, coral) border-box;
  border: 5px solid transparent;
  border-radius: 50px;
}

Result:

Hello World!

💡 NOTE: To control the inner border-radius while maintaining the gradient you should use a slightly different approach. Check out my article on inner border-radius.

Demo

Complete examples with code available on CodePen:

See the Pen Untitled by Tippingpoint Dev (@tippingpointdev) on CodePen.

Like this article? Share it on:
Tags: