Gradient Border Morph
Slowly turning conic-gradient border; on hover, focus or tap, its four colours blend over 0.8 s into a warm palette.
Updated
This effect is part of Effect.Labs — 840 vanilla effects, some free, some premium. Utilities has 43 effects, including 3 free. Explore the category →
3 usage examples



How it works
The .gbm-box (200 × 120 px, 12 px radius) places a ::before layer behind itself, 3 px larger on every side, filled with a four-colour conic-gradient: indigo #6366f1, violet #8b5cf6, magenta #d946ef, pink #ec4899, then back to indigo. A second layer, ::after, in the box colour, hides the inside 3 px in from the edge: what is left is a 6 px colour band straddling the edge, making a full turn every 6 s.
On hover, or when something in the box has focus (:focus-within), the four colours move to amber #f59e0b, red #ef4444, pink #ec4899 and cyan #06b6d4, and the band blurs by 2 px. The change takes 0.8 s and goes through every in-between shade: halfway, the indigo has already turned into a mauve leaning toward ochre.
This blend exists because the four colours are variables registered with @property as <color>, and the angle as <angle>. A gradient written out directly cannot transition: the browser swaps one image for the other. Here it interpolates each colour on its own and recomputes the gradient on every frame (measured in all three engines: 99,102,241 → 142,118,173 → 194,138,92 → 245,158,11 within 0.9 s for the first colour).
The label is a link, .gbm-link, stretched over the whole box by its ::after; it makes the box a real clickable target that the keyboard can reach, and it is what triggers the warm palette on focus and tap.
Accessibility
- Keyboard: Tab stops on the box link; the warm palette arrives as on hover and a white ring (
--gbm-ring) frames the box when focus comes from the keyboard. In Safari, whether Tab stops on links depends on the browser's keyboard setting (Option+Tab otherwise). - Touch: tapping the link changes the palette in Chromium, Firefox and WebKit (measured with a simulated touch screen); it goes back when you tap elsewhere.
- Reduced motion: with
prefers-reduced-motion: reduce, the gradient stops turning and the palette changes at once, with no blend; the 2 px blur on hover stays. - Colour alone: the palette change should not be the only sign of a state (selected, confirmed); add text or a check mark if the box is used to pick something.
Browser compatibility
Pure CSS, no JavaScript. Measured in Chromium 151, Firefox 153 and Playwright's WebKit 26.5: visible border, rotation, real blend of the four colours, two independent copies, hover, Tab, touch, 390 px and reduced motion. Minimum versions from @mdn/browser-compat-data: rotation and blend rely on @property (Chrome 85, Firefox 128, Safari 16.4); the stretched link uses inset (Chrome 87).
Without @property, the colours go through ordinary variables and the angle has a fallback value inside var(): the border still shows, does not turn, and changes palette instantly on hover (checked by removing the @property rules in Chromium).
The code
HTML structure to paste into your page (the CSS + JS come with your purchase):
<div class="fx-0771-root">
<div class="gbm-box">
<a class="gbm-link" href="#gradient-morph">Gradient Morph</a>
</div>
</div>
One-time payment, no subscription — the code is yours forever
Customize
Options passed to the API or data-* attributes:
| Option / property | Default | Effect |
|---|---|---|
--gbm-from-1 to --gbm-from-4 |
#6366f1, #8b5cf6, #d946ef, #ec4899 |
The four gradient colours at rest (the first one also closes the loop). |
--gbm-to-1 to --gbm-to-4 |
#f59e0b, #ef4444, #ec4899, #06b6d4 |
The four colours on hover, focus and tap. |
--gbm-morph |
.8s |
Length of the blend from one palette to the other (and of the blur). |
--gbm-speed |
6s |
Time for one turn of the gradient. |
--gbm-w, --gbm-h, --gbm-radius |
200px, 120px, 12px |
Size and corner radius; the border follows the radius and the width never exceeds the container. |
--gbm-fill |
#0a0a0f |
Box background, which also acts as the inner mask. |
--gbm-ring |
#fff |
Colour of the keyboard focus ring. |
FAQ
background is not animatable: between two gradients, the browser swaps images in one go. By registering each colour as a <color>, the transition works on four plain colours, which the browser knows how to mix; the gradient using them follows, frame after frame.<a> or <button> inside it with the gbm-link class, as in the library example: its ::after makes the whole box clickable, and its focus triggers the warm palette. A <button> keeps the browser's background and border: add background: none; border: 0; font: inherit to it. Adjust --gbm-h and --gbm-radius for a pill shape.--gbm-from-* variables greys close to the background, as in the dance school timetable. The blend then starts from an almost neutral outline and goes to the bright colours of --gbm-to-*.