Examining a random button I saw online Ko-fi's new "Promote your page" button caught my eye. I took a look at its implementation and re-made it myself. 26 coding, web dev, css
Examining a random button I saw online

I took a look at my ko-fi page the other day and noticed the new "Promote your page" button they added to the middle of the dahsboard. It has a fancy lookin' rainbow outline that makes it stand out pretty well. For some reason I decided to take a look at how they managed to pull that off, since border gradients with rounded corners isn't all that straightforward in CSS.

Ko-fi's button with its rainbow border and rounded corners.

When I looked into it, the implementation was actually really fascinating. It's a single anchor element with some relatively simple styling... except for one property: the background. Here's the important styling on it; take a look at the background this thing has:

<style> .ko-fi_button { width: 166px; height: 63px; font-size: 16px; display: flex; align-items: center; justify-content: center; background: radial-gradient(circle at 100% 100%, red 0, red 27px, transparent 27px) 0% 0%/30px 30px no-repeat, radial-gradient(circle at 0 100%, red 0, red 27px, transparent 27px) 100% 0%/30px 30px no-repeat, radial-gradient(circle at 100% 0, red 0, red 27px, transparent 27px) 0% 100%/30px 30px no-repeat, radial-gradient(circle at 0 0, red 0, red 27px, transparent 27px) 100% 100%/30px 30px no-repeat, linear-gradient(blue, blue) 50% 50%/calc(100% - 6px) calc(100% - 60px) no-repeat, linear-gradient(green, green) 50% 50%/calc(100% - 60px) calc(100% - 6px) no-repeat, conic-gradient(#fa4b4b 0%, #e8e86d 16.67%, #56adff 50%, #ed80ed 83.33%, #fa4b4b 100%) } </style> <div class="ko-fi-button"> Ko-fi&s Button! </div>

In order to make this all a bit easier I took a few minutes to recreate the button locally with only the necessary styling. The font isn't exact, but otherwise it's the same. Here it is zoomed in 250%, since it's a bit small normally.

My recreation of Ko-fi's button.

That big block of gradients is after I cleaned it up with better formatting. You can see that it's actually SEVEN gradients layered on top of each other. It can be hard to visualize what each of these do, so let's try fiddling with things to see how it works. First, let's change the colors on the first radial gradient - anything very visible works, so let's make it red.

radial-gradient(circle at 100% 100%, red 0, red 27px, transparent 27px) 0% 0%/30px 30px no-repeat,

And the result...

The top left corner turned red.

Interesting. A quick look at the other 3 radial gradient positions (the two percentages after the closing parentheses) shows they're each nestled in one of the corners. The other set of numbers with pixel values are the size of the gradient - all 30 pixels square. It looks like they're putting circles in the corners to simulate the rounded corners, and hiding most of the circle by constraining the gradient size. Let's highlight all the corners:

All of the circles in the corners are visible now that they're colored red

Ok, I think I have an idea of how they're doing it now, but let's keep going and highlight the linear gradients with different colors and remove the border radius to get a clearer picture of what's going on:

The center of the button is blue and green.

So they added a few more gradients to cover the rest of the button, and the final gradient is responsible for the actual rainbow in the background. The rainbow covers the whole button, the linear gradients cover the bulk of the center of the button, and the radial gradients create circles at the corners that perfectly match the button's border radius, leaving a 3 pixel gap where the rainbow can still show through. Then all of the radial and linear gradients are given the same, flat color so the parts mesh together.

This is a really fascinating solution, but to my intermediate-skill CSS eye this seems very overengineered. I couldn't help trying to get the same effect, but simpler. This is what I came up with:

<style> .my-button-background { width: 166px; height: 63px; font-size: 16px; background: conic-gradient(#fa4b4b 0%, #e8e86d 16.67%, #56adff 50%, #ed80ed 83.33%, #fa4b4b 100%); border-radius: 300px; display: flex; align-items: center; justify-content: center; } .my-button-contents { width: calc(100% - 6px); height: calc(100% - 6px); background-color: #202020; border-radius: 280px; display: flex; align-items: center; justify-content: center; } </style> <div class="my-button-background"> <div class="my-button-contents"> My button! </div> </div>

My version uses 2 div elements. The top level one has much of the same styles as Ko-fi's except the background is only the conic rainbow gradient. The inner div is centered using align-items/justify-content, has an opaque background, and most importantly, a size that's just a few pixels smaller than the top level div. Add a border radius and the inner div covers exactly the areas we want covered while leaving the edges uncovered so the rainbow can show through.

The final result:

My version of the button, using 2 divs.

I think mine actually looks a little better than Ko-fi's. If you look closely at the inner edge of the rainbow, Ko-fi's has some chunky pixels while mine is a lot smoother. Likely due to gradients not having the same antialiasing as border radii.

I'm still not sure why I felt compelled to look at the styling on the button, why I wasted time figuring out the wild gradients, why I remade it myself, or why I decided to write a blog post about it, but hopefully someone finds this at least mildly interesting.

Load Comments
Comments
Qwarq
This is my test comment
Hi! I'm Qwarqbot! I'm the autonomous lab assistant. What can I do for you?
GUEST BOOK VIEW | SIGN
0 / 500
Use my button on your site!