How to do a dashed border with a gradient and a border-radius in css?
Closest I could get to was with an svg background-image:
This looks fine if you have a 100px to 100px box (see 2cnd picture). But the border should fit on any box. As soon as you increase width and height to another aspect ratio, it breaks, especially the border-radius (see 1st picture).
i also tried several different solutions, but nothing works as expected...

36 Replies

I would try a pseudo element with a 2px dashed transparent border, bg clip/origin to the border-box and mask padding-box exclude. Then the bg image of conic gradient . I'm on mobile and I'm trying not to hand out solutions anymore anyways (no one learns if they just copy and paste) but lmk if you have questions.
Does this approach only work with a white background? In my case the background has to be transparent
One method is to place the "border" gradient on a pseudo element and use a mask to only allow the edges to be visible, leaving the content area transparent.
the responsive squishing and stretching of the corners can be fixed by using
border-image
instead of background-image
This is how i would do it https://codepen.io/tok124/pen/ZYEYxEZ
Just make sure to include the vendor prefixes so that it works on chromium based browsers

i have autoprefixer enabled in codepen so you don't really see the prefixes unless you compile the code
Yea the mask will make it transparent except for the gradient in the borderbox “padding-box exclude “
Unprefixed for
mask
is pretty well supported ! The purple border shows versions when prefix was required. Although with autoprefixer it doesn’t hurt to include anyway ✨
Yeah, but you need it for the mask-composite 🙂
Aha that’s right , how quickly I forget ; just used it a few months ago and had to prefix for exclude
Yeah 😄
Switching to
border-image
doesn't show anything anymore, do i need to adapt the svg?That really looked promising, but as soon as you change the width/height the apperance breaks :/

I also think
border-image
doesn't account for border-radius
?Strange... Works fine for me...
Correct
@oemerSee here, works perfectly fine
Maybe you changed the width/height of the pseudo element and thats why it looked messed up...
But anyway, if it does look messed up on any width/height, just adjust the mask gradient
If you compare it to a normal css border, the line lenght and distance is different:

But don't I have to adjust it for any case where i use this style then? The card could have different dimensions for different use cases
@Tok124 (CSS Nerd)
I really think this is onlypossible with javascript, where you get the dimensions of the container and do some calculations with it.. which i would like to avoid because of SSR
Yep you can’t use border radius on border-image
Yeah. this is because i have used % unit. Idk if there is any other unit that would work better, perhaps vmin/vmax unit, i never really using these units, but maybe they could be useful here, otherwise you may have to go with em/rem/px unit
the radius of the corner is already included in the SVG image so
border-radius
wouldn't be necessary. or am i missing something?But yeah if you have a box like this, then 10% on the width is greater than 10% on the height, as you can probably imagine, that's why you end up with this problem, it's due to the % unit in mask gradient

But yeah if no other unit works you may need to use JS to calculate the correct % amount for the height
I see, if play around with values, it changes yeah
Yeah 🙂
would love to avoid javascript, but with px values it seems to be tricky
Otherwise you can use a conic-gradient, that works too, it may work a little better, but then there is a new problem, the corners may look kinda strange...

also interesting, but there are always buggy artefacts depending on which size you go for unfortunatelyy.. not only the corners


Hopefully CSS will support this in the future
Regardless, I learned a lot here, you guys are awesome
I got such an interesting result with a repeating conic gradient too, it looked like a pattern
For the future take a look at the
border-area
value for background-clip
. It's only in Safari right now but hopefully Chrome and Firefox will start to play around with it this year. To be honest it's not the best solution for this (it's a bit clunky and hacky to reuse background and set the border to transparent) but it's something we got a browser to actually work on... https://github.com/w3c/csswg-drafts/issues/9456#issuecomment-2325278729
also tinkered with your svg a bit to get it to work in border-image
as expected. Needed to remove the viewbox to make it a fixed size: https://codepen.io/jsnkuhn/pen/RNwNYdzOh wow, that looks really good! I am honestly baffled how deeply you guys understand CSS. I just checked all diffs. You are using a fixed height, not percent. You added
32 / 32px round
to the border-image
prop. You removed the viewBox
and also vector scaling. If you miss one of those, it just breaks.
I am really wondering how you learned this? Do you guys just do trial and error or is this your profession? It seems really complicated and very detailed.
In my company i am the kind of "CSS guy" but i feel really noobish compared to you guysupdated the pen I made above to use the
border-image-*
long hands to give a better idea of what's going on. MDN article is probably the best place to find more info: https://developer.mozilla.org/en-US/docs/Web/CSS/border-image