Utilities✨ Premium

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.

CSSHoverGradient

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

“Extend loans” button in a library account — Gradient Border Morph example 1

① “Extend loans” button in a library account

WhenIn the reader account of the Brecolune library, under the three items due back on 3 December, a wide button offers to extend them all; its border turns gently in violet and shifts to amber and cyan as soon as the mouse or focus lands on it.
WhyIt is the only action on the page: the turning border points to it without a loud colour, and the palette blend answers the gesture without a jump, which stays pleasant on a button people often hover before making up their mind.
Settings--gbm-w: 300px; --gbm-h: 46px; --gbm-radius: 23px; --gbm-fill: #131620; default palettes and timings; the .gbm-link link holds the button text.
Class timetable of a dance school — Gradient Border Morph example 2

② Class timetable of a dance school

WhenOn the Grisaunelle dance school page, the six Saturday classes (early years, ballet, hip-hop, contemporary, floor barre, jazz) form a grid of cards with the time and the studio; at rest their grey outline barely turns, and the hovered card flares up in amber, red, pink and cyan.
WhyWith the resting palette set to two greys, the effect becomes a hover marker for a whole grid: nothing shouts at rest, and the targeted class stands out clearly before the click that opens its page.
SettingsOne root for all six cards (each class name is the .gbm-link link), in a 3-column grid; --gbm-w: 100%; --gbm-h: 104px; --gbm-fill: #14131c; --gbm-from-1 to --gbm-from-4 as #2a2838 / #3b3850; --gbm-speed: 8s; --gbm-morph: .6s.
Seasonal banner of a delicatessen — Gradient Border Morph example 3

③ Seasonal banner of a delicatessen

WhenAt the top of the Maison Valdrouet home page, the banner “The autumn selection is here” is edged with slowly turning summer greens; when the mouse passes over, they shift to the russets and ochres of autumn.
WhyThe palette blend tells the banner's story (one season giving way to the next) instead of being mere ornament; on a light page, the dark box keeps the border readable.
Settings--gbm-w: 100%; --gbm-h: 148px; --gbm-radius: 16px; --gbm-fill: #2b241a; at rest #4d7c0f #84cc16 #a3e635 #65a30d, on hover #b45309 #ea580c #dc2626 #ca8a04; --gbm-speed: 12s.

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).

Chrome 87+✓ Full (measured in version 151)
Firefox 128+✓ Full (measured in version 153); from 83 to 127, static border and palette switching without a blend
Safari 16.4+✓ Full (measured in WebKit); from 14.1 to 16.3, static border and switch without a blend
Edge 87+✓ Full (Chromium engine)
Safari iOS 16.4+✓ Full, warm palette when the link is tapped (measured in touch WebKit)
Chrome Android 87+✓ Full (Chromium engine)

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):

index.html — structure
<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 / propertyDefaultEffect
--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

A gradient 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.
Keep the box and put your <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.
Yes: give the four --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-*.