Create a gradient border in CSS
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.