Gradient borders have gone full Technicolor dreamcoat in the world of web design. Instead of static, plain-jane edges, we can now add animated gradient borders for your Webflow projects. If you've ever wanted a moving, groovy outline around your elements, you've come to the right place. In this guide, we’ll cover two different ways to create animated gradient borders for any project: one CSS-only solution, and one using GSAP (GreenSock Animation Platform) for maximum customization and flexibility.
I'd like to note that I picked up this CSS from Kevin Powell's excellent YouTube video, who adapted it from a CodePen by Gayane Gasparyan. Check the above section for those acknowledgments. When it came down to it though, when I was working on a project for Relume, our design included a bezel and a strict tolerance (i.e. no negative inset) to get the effect just right. So let's explore both options!
Option 1: Animated Gradient Borders with CSS Conic Gradients and @property
Let’s kick things off with pure CSS. This solution animates the border gradient in a sleek, lightweight way. No libraries required—but there's a catch or two to be aware of.
Step 1: Set Up the CSS Variables
Start by defining a set of variables for our flaming gradient colors:
:root {
--flamingo-queen-1: #e799ff;
--flamingo-queen-2: #f500b4;
--flamingo-queen-3: #b70045;
--flamingo-queen-4: #661b00;
}
These colors will give you a rich, fiery gradient. Adjust the colors if you’re feeling a different vibe. We’ll be blending these colors together into a rotating conic gradient.
Step 2: Define the Animated --angle
Property
CSS @property
syntax allows us to animate custom properties. Here’s what it looks like:
@property --angle {
syntax: "<angle>";
initial-value: 0deg;
inherits: false;
}
By setting up the --angle
variable as an angle, we can smoothly animate it later. Note: as of now, Webflow doesn’t support @property
in designer view, so don't expect the CSS solution to just work there. You'll have to publish and inspect on the live page for this one.
Step 3: Create the Conic Gradient Border
Now we apply the animated conic gradient border to our element:
.box {
position: relative;
background: linear-gradient(#303030, #222222);
color: white;
aspect-ratio: 1 / 1;
display: flex;
align-items: center;
justify-content: center;
border-radius: 8px;
}
.box-1::before,
.box-1::after {
content: "";
position: absolute;
inset: -2px;
border-radius: inherit;
background-image: conic-gradient(
from var(--angle),
var(--flamingo-queen-1),
var(--flamingo-queen-2),
var(--flamingo-queen-3),
var(--flamingo-queen-4),
var(--flamingo-queen-3),
var(--flamingo-queen-2),
var(--flamingo-queen-1)
);
animation: spin 2.5s linear infinite;
}
.box-1::after {
filter: blur(14px);
}
Here’s the rundown:
::before
and::after
pseudo-elements act as the border layers, providing a cool, diffused effect when one is blurred. Pseudo element can pretty much be thought of as separate elements, we jsut tack them on to a parent of sorts to reducediv
usage.- The
inset: -2px;
pushes the gradient border outside the actual box, giving it a border-like effect. (Be aware that this negative margin can mess with layout alignment—watch out for that.) If you need your cards to line up erfectly with other elements in your design, especially for wide borders, you may need to compensate with margin/padding elsewhere. This is one of the main reasons I still really like the GSAP solution. However, for 1px borders, this works pretty damn well I gotta say!
Step 4: Add the Animation
The animation is simple: we gradually increase the angle of the gradient using keyframes:
@keyframes spin {
to {
--angle: 360deg;
}
}
And that’s it for the CSS approach! But hold on—before you dive in, let’s go over the pros and cons:
Pros and Cons of the CSS-Only Solution
Pros:
- Performance: Runs smoothly in most browsers (worked great in Safari, Chrome, and Firefox in my testing). Caniuse confirms.
- Less Code: Only a few lines to create a popular effect.
Cons:
- Limited Support:
@property
doesn’t work in Webflow directly—gotta publish and view there. Workflow busted. - Hard to Customize: Getting fancy with it could be difficult, in which case you'd probably want to reach for GSAP anyways...
Option 2: Animated Gradient Borders with GSAP
If you need something more flexible, or if you want to play around with extending the animation, then GSAP is the way to go. This solution requires a little JavaScript but offers extensive customization.
Step 1: Set Up the Markup
Here’s the basic structure we’ll use for our GSAP-animated gradient:
<div class="box box-2">
<div class="gradient blur"></div>
<div class="gradient"></div>
<div class="inner">GSAP</div>
</div>
The extra <div>
elements give GSAP multiple layers to work with, allowing for more complex animations (blur, inset shifts, opacity changes, you name it).
Step 2: Spin the Gradient with JavaScript
To animate our gradient with GSAP, we’ll use a simple timeline to rotate the gradient endlessly:
function spinGradients() {
let angle = 0;
const duration = 5;
gsap.timeline({
repeat: -1,
ease: "none",
duration,
onUpdate: function () {
angle = (angle + 360 / (duration * 60)) % 360;
const existingGradient = gsap.getProperty(".gradient", "backgroundImage");
const gradientWithAngleInjectedInProperPlace = existingGradient.replace(
/from \d+(\.\d+)?deg/,
`from ${angle}deg`
);
gsap.set(".gradient", {
backgroundImage: gradientWithAngleInjectedInProperPlace
});
}
});
}
spinGradients();
This function:
- Sets an angle that increments over time.
- Updates the gradient rotation angle to create a smooth spinning effect.
- Watch out for that little bit of regex in there. Basically it looks for the angle defined in the conic-gradient statement and injects the new value in there.
Step 3: Add Hover Effects
Now let’s add a hover effect to add extra interactivity:
function hoverBoxAnimation(event, insetOffset, opacity) {
const el = event.target;
const bezel = el.querySelector(".bezel");
const inner = el.querySelector(".inner");
const blur = el.querySelector(".blur");
const tl = gsap.timeline();
tl.to(bezel, {
inset: insetOffset
})
.to(inner, {
inset: insetOffset * 2
}, "<")
.to(blur, {
opacity
}, "<");
}
const hoverBoxes = document.querySelectorAll(".box-4");
hoverBoxes.forEach((hoverBox) => {
hoverBox.addEventListener("mouseenter", (event) =>
hoverBoxAnimation(event, 2, 1)
);
hoverBox.addEventListener("mouseleave", (event) =>
hoverBoxAnimation(event, 0, 0)
);
});
This code listens for hover events and plays with the inset
and opacity
of the elements for a cool 3D-ish effect. It’s eye-catching and super smooth thanks to GSAP’s efficient rendering.
Pros and Cons of the GSAP Solution
Pros:
- Highly Customizable: Easily modify colors, durations, or add hover animations.
- Fits in your layout: No negative insets to wrestle with.
- Interactive: It’s easier to add advanced hover states and other interactions.
Cons:
- More Code: The solution is more complex and involves JavaScript.
- External Library: Adding GSAP means including an additional library. If you follow my stuff, you're probably using it anyways so what the heck!
Final Verdict
If you’re after a lightweight, out-of-the-box animation, go with the CSS-only solution—simple, fast, and visually impactful. But if you want to create something interactive or customize every single animation detail, GSAP is the heavyweight champ you want in your corner. With these techniques in your toolkit, your Webflow projects are going to have borders so animated they’ll basically be alive.