Knowledge Hub
For manager
Headless CMSFor developer
Web FrameworksStatic Site GeneratorsServerless DatabasesMonoreposHostingPIMLearn
GuidesTutorialsAdopt
Case studiesCreating a gradient border and animating it in CSS can be tricky. Let's dive into some ways to do it together in this experiment.
<article class="card">
<h1 class="card__title">Audit your project</h1>
<p class="card__description">As your business grows, so does your codebase.</p>
<div class="media-object">
<div>
<h2 class="media-object__title">Your frontend doesn't have to be a mess.</h2>
<a class="media-object__button">Get Your Audit</a>
</div>
<div class="media-object__thumbnail"></div>
</div>
<div class="card__actions">
<a class="card__button">Example Audit</a>
<a class="card__button">Paid & free Plans</a>
</div>
</article>
For a border without radius needs, use border-image:
.media-object {
border: 1px solid;
border-image: conic-gradient(#381D6A 80%, #E0D1FF 88%, #E0D1FF 92%, #381D6A 100%) 1;
}
To maintain radius with no transparency:
.card {
isolation: isolate;
}
.media-object {
--border-width: 1px;
--radius: 24px;
--bg-color: #0F0620;
position: relative;
border: var(--border-width) solid transparent;
border-radius: var(--radius);
background-color: var(--bg-color);
background-clip: padding-box;
}
.media-object::before {
content: " ";
position: absolute;
inset: calc(var(--border-width) * -1);
z-index: -1;
border-radius: inherit;
background-image: conic-gradient(#381D6A 80%, #E0D1FF 88%, #E0D1FF 92%, #381D6A 100%);
}
You can combine backgrounds and use more background properties to achieve the same effect.
.media-object {
--border-width: 1px;
--radius: 24px;
--bg-color: #0F0620;
border: var(--border-width) solid transparent;
border-radius: var(--radius);
background-image: linear-gradient(var(--bg-color) 0 0),
conic-gradient(#381D6A 80%, #E0D1FF 88%, #E0D1FF 92%, #381D6A 100%);
background-clip: padding-box, border-box;
background-origin: padding-box, border-box;
}
If you need both transparency and radius, CSS masking is the way.
.card {
isolation: isolate;
}
.media-object {
--border-width: 1px;
--radius: 24px;
position: relative;
border-radius: var(--radius);
border: var(--border-width) solid transparent;
}
.media-object::before {
content: " ";
position: absolute;
inset: calc(var(--border-width) * -1);
z-index: -1;
border: inherit;
border-radius: inherit;
background-image: conic-gradient(#381D6A 80%, #E0D1FF 88%, #E0D1FF 92%, #381D6A 100%);
background-origin: border-box;
mask: linear-gradient(black, black),
linear-gradient(black, black);
mask-clip: content-box, border-box;
mask-composite: exclude;
}
We can use CSS Houdini to animate a gradient border.
.media-object {
--border-width: 1px;
--radius: 24px;
border: var(--border-width) solid;
border-image: conic-gradient(from var(--angle), #381D6A 80%, #E0D1FF 88%, #E0D1FF 92%, #381D6A 100%) 1;
animation: spin 3s linear infinite paused;
}
.media-object:hover {
animation-play-state: running;
}
@property --angle {
syntax: "<angle>";
inherits: true;
initial-value: 0turn;
}
@keyframes spin {
to {
--angle: 1turn;
}
}
For browsers that don't support Houdini, you can utilize the CSS @supports
feature. This ensures users still receive the gradient, even if they can't view the animation.
@supports not (background: paint(something)) {
.media-object {
border-image: conic-gradient(#381D6A 80%, #E0D1FF 88%, #E0D1FF 92%, #381D6A 100%) 1;
}
}
No radius, but allows a transparent background and eliminates the need for an extra element, avoiding z-index issues.
Provides a radius but lacks transparency and may pose potential z-index challenges.
Gives us the radius but doesn't offer transparency; it bypasses z-index complexities.
Offers both radius and transparency but presents a z-index drawback.
I made the following flowchart to illustrate how you can choose the best option.
If a radius isn't necessary, opt for the border-image technique. Need a radius? If transparency isn't required, use multiple backgrounds. For a transparent background with a radius, CSS masking is the solution.
Join the conversation initiated by Lea on GitHub regarding a potential CSS value for gradient borders.
For a live demo and source code, check out our GitHub repository: Bejamas Experiments.