DEV Community

Cover image for Create Animated Borders Using Only CSS.
Simon Bittok
Simon Bittok

Posted on

Create Animated Borders Using Only CSS.

I first noticed animated borders on deno.com a while back. Their feature cards had these smooth, glowing green lines moving around the edges. I thought to myself,

“Wow… that must be some incredibly complex Javascript magic.”

I promised myself that one day I’d learn how to build something just as cool.

Turns out… you can create animated borders using only HTML and CSS and it’s way easier than I expected.

Before we embark on this will be our final product.

Starting Up

Lets begin with some basic HTML.

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>Animated Borders</title>
    </head>
    <body>
        <div class="card"></div>
    </body>

</html>
Enter fullscreen mode Exit fullscreen mode

Create a CSS file, link it to our HTML and some basic styling to the body & the box:

<link rel="stylesheet" href="index.css" >

body {
    background: oklch(0.1743 0.0227 283.7998);
    margin: 0;
    padding: 0;
    height: 100svh;
    display: flex;
    justify-content: center;
    align-items: center;
}

.card {
    height: 400px;
    aspect-ratio: 1/1;
    background: oklch(0.2284 0.0384 282.9324);
    border-radius: 12px;
}

Enter fullscreen mode Exit fullscreen mode

CSS After & Before Pseudo Elements

MDN docs by mozilla says the following about CSS pseudo elements.

A CSS pseudo-element is a keyword added to a selector that lets you style a specific part of the selected element(s).

So from my understanding pseudo elements help you to style specific elements without additional HTML.

We'll create a new visual layer behind the card using ::before

.card::before {
    content: "";
    height: 100%;
    width: 100%;
    background: conic-gradient(
        from 0deg at center,
        red,
        orange,
        blue,
        purple,
        red
    );
    position: absolute;
    z-index: -2;
    border-radius: inherit;
    padding: 2px;

}

.card {
/* add the following styles to the card */
    position: relative;
    display: flex;
    justify-content: center;
    align-items: center;

}

Enter fullscreen mode Exit fullscreen mode

The padding on the ::before pseudo element serves as our border, you can make it as thick as you wish (or as thin). You will now see a colourful border around the card.

Now to make the "border" animated we now employ the sibling to ::before pseudo element, the ::after pseudo element.

The latter works exactly as the former element, so just add it to the existing ::before element and separate them with a comma.

We will use it to give our 'border' a softer glow.

.card::before, .card::after {}
.card::after {
    filter: blur(8px); /* gives a softer effect. */
}
Enter fullscreen mode Exit fullscreen mode

@propery rule

We define a CSS variable --angle for controlling the gradient rotation:

@property --angle {
    syntax: "<angle>";
    initial-value: 0deg;
    inherits: true;

}

.card::before, .card::after {
    background: conic-gradient(
        from var(--angle) at center,
        red,
        orange,
        blue,
        purple,
        red
    );
/* as it were */
}

Enter fullscreen mode Exit fullscreen mode

@keyframes rule

The conic gradient now rotates a full circle every 4 seconds!
Feel free to tweak the speed or colours to your heart desires.

.card::before, .card::after {
/* as it were */
    animation: rotate 4s linear infinite;
}

@keyframes rotate {
    to {
        --angle: 360deg;
    }

}

Enter fullscreen mode Exit fullscreen mode

Note

The @property rule is currently best supported in Chromium browsers. If you need broader compatibility, you can animate using other techniques such as transform or animating a mask.

Full Source Code

Source code

If you build something cool with this idea, drop a link.
I’d love to check it out!
If you also have any suggestions or recommendations feel free to reach out.
Follow me for more beginner-friendly CSS UI tricks

Top comments (0)