Find out more CSS tricks at css-tip.com
We all know the property border-image
that allows us to add any kind of images (including gradients) as borders.
.box {
border: 10px solid;
border-image: linear-gradient(45deg,red,blue) 10;
}
Unfortunately, border-radius
isn't supported with border-image
and it's painful to find tricks to obtain rounded borders having a gradient.
Here is a trick that will produce such a result. No complex code, No SVG, or multiple elements are required! only two lines of CSS code using the mask
property.
.box {
border-radius: 50px; /*1*/
border: 10px solid transparent; /*2*/
background: linear-gradient(45deg,red,blue) border-box; /*3*/
mask: /*4*/
linear-gradient(#000 0 0) padding-box,
linear-gradient(#000 0 0);
mask-composite: exclude; /*5*/
}
Explanation
(1)(2): Those lines are trivial.
(3): We apply a gradient as background and we make its origin the border box (by default it's the padding box).
(4): Using the mask
property, we apply two opaque layers. The bottom one will cover the whole element and the top one will cover only the padding box (so it will not cover the border area)
(5): We exclude the top layer from the bottom one so that only the border area will be shown!
That's it!
Now you can adjust the border, gradient, and radius as you want. The only drawback is that this will mask the content so we can move the code to a pseudo-element instead
.box {
position: relative;
}
.box::before {
content: "";
position: absolute;
inset: 0;
border-radius: 50px;
padding: 10px;
background:linear-gradient(45deg,red,blue);
mask:
linear-gradient(#000 0 0) content-box,
linear-gradient(#000 0 0);
mask-composite: exclude;
}
I replaced the border with padding to make the code shorter but the logic remains the same: we exclude the content area from the padding area so only padding will remain visible
Top comments (33)
Thanks
This helped enormously, thank you!
Thanks, it could work in some situations, although two issues:
if you are adding z-index:-1 to the pseudo element you need to add z-index:0 to the main element to avoid the issue OR don't use z-index at all and add pointer-events:none to the pseudo element
Thank you! That does fix it!
Thank you so much! Even if I ended up not using your solution, you helped me find out the best way to do this dev.to/noriste/production-grade-gr... 😊
But what if i need to make a background colour as well? for instance, gradient as well
in this case, you don't need mask or pseudo element simply do
This is SO much cleaner than all the "gradient border"-articles you find around the web — love the 4-char alpha-hex. Thank You!
Well i tried what you said, but it looks very much differently from what i want to archive and it's so sad.
PS: i decided simply to export the background with border as a background (svg), the simplest way
thanks for the tip, will try.. my designer made this, at first i tried it with a border-image-source but it doesn't work with border-radius, of course
Thus just saved me more digging, thanks muchacho
Thanks for this but doesn't work in Safari, only Chrome and Firefox
Nice! thanks.
Nice article, and nice seeing you here :)
thanks :) will try to bring some tricks and some hacks to dev.to ;)
Where can we find pre-made gradients?
what kind of pre-made gradients?
I mean gradient which made by someone to use. Ready to use gradients.
After some digging around the internet, I found this
eggradients.com/
So pretty!