Border spin
Animated rotating gradient borders. Add border-spin to any element with a conic border gradient to spin it continuously.
Browser support
The animated angle needs @property, which is the older of the two, but there is nothing to spin without a border gradient, so the gradient's floor is the one that applies. Live status for both is at the foot of this page.
This animation does not stop itself
border-spin carries no prefers-reduced-motion query of its own, so a reader who has asked their system for reduced motion still gets the spin. Ask for it through the variant instead:
<div class="border-4 border-conic-0 motion-safe:border-spin"></div>motion-reduce:animate-none turns it off the other way round. Neither needs !, and every other variant works the same: border-spin declares nothing but the animation, so it has no specificity to out-rank.
Quick reference
| class | styles |
|---|---|
| border-spin | animation: border-spin var(--jib-border-spin-duration) linear infinite var(--jib-border-spin-direction) |
| border-spin-reverse | --jib-border-spin-direction: reverse |
| border-spin-duration-<number> | --jib-border-spin-duration: <number> * 1000ms |
| border-spin-duration-<name> | --jib-border-spin-duration: var(--jib-border-spin-duration-<name>) |
| border-spin-duration-[<value>] | --jib-border-spin-duration: <value> |
Basic usage
Add border-spin to rotate the gradient continuously. The default duration is 1s.
Reverse
border-spin-reverse turns the rotation the other way. It declares only the direction, so it composes with everything else: pair it with a duration, a variant, or neither.
Two rings turning against each other read as a single mechanism rather than two spinners:
Spin duration
Use border-spin-duration-<number> where n is in seconds (multiplied by 1000ms):
Using a custom value
Use bracket notation for custom durations:
Naming your own durations
border-spin-duration-* reads the --jib-border-spin-duration-* theme namespace, so a project can name its speeds once and use them everywhere:
@theme {
--jib-border-spin-duration-slow: 4s;
--jib-border-spin-duration-brisk: 600ms;
}<div class="border-4 border-conic-0 border-spin border-spin-duration-slow"></div>Using a custom variable
Reference CSS custom properties with the typed bare-value syntax (type:--var):
| Utility | Type hint | Example |
|---|---|---|
border-spin-duration-* | time | border-spin-duration-(time:--spin-speed) |
Custom properties inherit, so the variable can live on an ancestor and every spinner below it follows. Changing it at runtime retimes them together:
<div style="--spin-speed: 2.5s">
<div class="border-4 border-conic-0 border-spin border-spin-duration-(--spin-speed)"></div>
<div class="border-4 border-conic-0 border-spin border-spin-duration-(--spin-speed)"></div>
</div>How it works
Registering --jib-border-gradient-angle as an <angle> through @property is what makes it animatable. Every conic border gradient starts from that angle, so border-conic-45 is a declaration of it, and a @keyframes animation rotates it from 0deg to 360deg. An animation beats a declaration by cascade origin rather than by selector weight, which is how border-spin takes the angle over while carrying no specificity of its own. --jib-border-spin-duration sets how long one turn takes, defaulting to 1s, and --jib-border-spin-direction is the animation-direction slot of the same shorthand, defaulting to normal. Because both are read out of the shorthand rather than redeclared beside it, border-spin-reverse and the duration utilities never restate the animation and so never have to out-rank it.
Import
Included in @import 'tw-jib-css'. To import individually:
@import 'tw-jib-css/border-gradient';Note: border-spin is part of the border-gradient module.
Baseline status
What these utilities are built on, live from the Web Platform Dashboard.