---
title: "Rotating Rainbow Border Button"
description: "A pill button whose thin gradient outline spins forever, with a blurred glow that blooms on hover."
canonical: "https://fx.statico.io/demos/resend-rainbow-button"
doc_version: "0.1.0"
last_updated: "2026-07-27"
date_modified: "2026-07-27T19:06:35-07:00"
source: "https://github.com/statico/cool-web-fx"
license: "Unlicense"
---

> Canonical HTML version: <https://fx.statico.io/demos/resend-rainbow-button>

# Rotating Rainbow Border Button

A pill button whose thin gradient outline spins forever, with a blurred glow that blooms on hover.

Seen on [Resend](https://resend.com/home) · credit Resend.

## How it works

This is the "Announcing Resend Forward" pill from Resend's hero, ported with the real CSS. The trick that makes a gradient *rotate* is a registered custom property:

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

Registering `--angle` as an `<angle>` type makes it **interpolatable**, so a `@keyframes rotate { to { --angle: 360deg } }` can smoothly tween it. A plain CSS variable would jump from 0 to 360 with no in-between frames; the typed `@property` is what lets `linear-gradient(var(--angle), …)` visibly spin.

The outer element carries `linear-gradient(var(--angle), #02fcef70 0%, #ffb52b70 50%, #a02bfe70 100%)` (Resend's real cyan→amber→violet, at ~44% alpha) and a 1px padding; an inner `<span>` painted the page's background color (`#0b0e14`) covers everything but that 1px rim, so only a thin rotating outline shows. The animation runs `30s linear infinite`.

A `::after` pseudo-element holds a brighter, fully-opaque copy of the same rotating gradient with `filter: blur(20px)`, sat behind the pill at `opacity: 0`. On `:hover` it fades to `0.9` and stretches (`transform: scaleX(1.1)`), blooming a soft glow; the face also darkens slightly. Both the rim and the glow share the same `--angle` keyframe so they stay in lockstep.

## Code

Copy this whole file. It is a complete, runnable HTML document — also served
verbatim at <https://fx.statico.io/effects/resend-rainbow-button.html>.

```html
<!doctype html>
<!--
  Rotating Rainbow Border Button  (Resend "Announcing Resend Forward" pill)
  ─────────────────────────────────────────────────────────────────────────────
  A rounded pill whose 1px border is a linear-gradient rotated forever by an
  animated CSS custom property. A registered @property --angle of type <angle>
  is interpolatable, so @keyframes can tween it from 0deg→360deg and the gradient
  visibly spins. A blurred duplicate of the same gradient sits behind the pill as
  a glow that fades in on hover.

  Source: extracted verbatim from resend.com/home (rainbow-border CSS). Colors,
  timings and structure are the real ones.

  Completely standalone — no CDN, no web fonts, no external assets.
-->
<html lang="en">
<head>
  <link rel="icon" href="data:,">
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Rotating Rainbow Border Button</title>
  <!-- a14y:begin head — machine-readable metadata; safe to delete when copying -->
  <meta name="description" content="A pill button whose thin gradient outline spins forever, with a blurred glow that blooms on hover.">
  <link rel="canonical" href="https://fx.statico.io/effects/resend-rainbow-button.html">
  <link rel="alternate" type="text/markdown" href="https://fx.statico.io/effects/resend-rainbow-button.md" title="Rotating Rainbow Border Button (Markdown)">
  <meta property="og:type" content="website">
  <meta property="og:site_name" content="cool web fx">
  <meta property="og:title" content="Rotating Rainbow Border Button">
  <meta property="og:description" content="A pill button whose thin gradient outline spins forever, with a blurred glow that blooms on hover.">
  <meta property="og:url" content="https://fx.statico.io/effects/resend-rainbow-button.html">
  <meta name="twitter:card" content="summary">
  <meta name="twitter:title" content="Rotating Rainbow Border Button">
  <meta name="twitter:description" content="A pill button whose thin gradient outline spins forever, with a blurred glow that blooms on hover.">
  <script type="application/ld+json">{"@context":"https://schema.org","@graph":[{"@type":"SoftwareSourceCode","@id":"https://fx.statico.io/effects/resend-rainbow-button.html#effect","name":"Rotating Rainbow Border Button","url":"https://fx.statico.io/effects/resend-rainbow-button.html","abstract":"A pill button whose thin gradient outline spins forever, with a blurred glow that blooms on hover.","description":"A pill button whose thin gradient outline spins forever, with a blurred glow that blooms on hover.","programmingLanguage":"HTML","codeSampleType":"full solution","runtimePlatform":"Web browser","codeRepository":"https://github.com/statico/cool-web-fx","license":"https://unlicense.org/","isBasedOn":"https://resend.com/home","mainEntityOfPage":"https://fx.statico.io/demos/resend-rainbow-button","dateModified":"2026-07-27T17:24:00-07:00","inLanguage":"en"},{"@type":"BreadcrumbList","@id":"https://fx.statico.io/effects/resend-rainbow-button.html#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https://fx.statico.io/"},{"@type":"ListItem","position":2,"name":"Rotating Rainbow Border Button","item":"https://fx.statico.io/demos/resend-rainbow-button"},{"@type":"ListItem","position":3,"name":"Standalone source","item":"https://fx.statico.io/effects/resend-rainbow-button.html"}]}]}</script>
  <style>.a14y-doc{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap;border:0}</style>
  <!-- a14y:end head -->
  <style>
    *, *::before, *::after { margin: 0; padding: 0; box-sizing: border-box; }

    html, body {
      width: 100%;
      height: 100%;
      overflow: hidden;
      background: #0b0e14;            /* Resend's dark background */
      display: flex;
      align-items: center;
      justify-content: center;
      font-family: ui-monospace, "SF Mono", "JetBrains Mono", Menlo, monospace;
    }

    /* A registered custom property of type <angle> — REQUIRED so that the
       browser can interpolate it inside @keyframes (a plain --angle would jump). */
    @property --angle {
      syntax: "<angle>";
      inherits: false;
      initial-value: 0deg;
    }

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

    /* The outer element IS the gradient ring. The inner <span> covers all but a
       1px rim, so only that rim of gradient shows. Both the ring and the glow
       share the same 30s linear spin. */
    .rainbow-border {
      position: relative;
      display: inline-flex;
      align-items: center;
      justify-content: center;
      padding: 1px;                  /* thickness of the visible gradient rim */
      height: 32px;
      border-radius: 9999px;
      background: linear-gradient(var(--angle), #02fcef70 0%, #ffb52b70 50%, #a02bfe70 100%);
      animation: rotate 30s linear infinite;
      cursor: pointer;
    }

    /* Blurred glow: a brighter copy of the gradient, hidden until hover. */
    .rainbow-border::after {
      content: "";
      position: absolute;
      inset: 0;
      z-index: -1;
      border-radius: 9999px;
      background: linear-gradient(var(--angle), #02fcef 0%, #ffb52b 50%, #a02bfe 100%);
      filter: blur(20px);
      opacity: 0;
      transform: scale(0.95, 0.6);
      transition: all 0.3s ease-out;
      animation: rotate 30s linear infinite;
    }
    .rainbow-border:hover::after { opacity: 0.9; transform: scaleX(1.1); }

    /* The button face. Slightly inset from the ring; matches the page bg so the
       pill reads as a thin glowing outline. */
    .rainbow-border span {
      display: inline-flex;
      align-items: center;
      gap: 6px;
      height: 30px;
      padding: 0 14px;
      border-radius: 9999px;
      background-color: #0b0e14;
      color: #e6e8ee;
      font-size: 13px;
      letter-spacing: 0.01em;
      white-space: nowrap;
      transition: all 0.2s ease-out;
    }
    .rainbow-border:hover span { background-color: #0b0e14d1; }

    .rainbow-border svg { width: 12px; height: 12px; }
  </style>
</head>
<body>
  <!-- a14y:begin body — visually hidden description; safe to delete when copying -->
  <div class="a14y-doc">
    <h1>Rotating Rainbow Border Button</h1>
    <p>A pill button whose thin gradient outline spins forever, with a blurred glow that blooms on hover.</p>
    <h2>How it works</h2>
    <p>This is the "Announcing Resend Forward" pill from Resend's hero, ported with the real CSS. The trick that makes a gradient *rotate* is a registered custom property:</p>
    <p>@property --angle { syntax: "&lt;angle&gt;"; inherits: false; initial-value: 0deg; }</p>
    <p>Registering --angle as an &lt;angle&gt; type makes it interpolatable, so a @keyframes rotate { to { --angle: 360deg } } can smoothly tween it. A plain CSS variable would jump from 0 to 360 with no in-between frames; the typed @property is what lets linear-gradient(var(--angle), …) visibly spin.</p>
    <p>The outer element carries linear-gradient(var(--angle), #02fcef70 0%, #ffb52b70 50%, #a02bfe70 100%) (Resend's real cyan→amber→violet, at ~44% alpha) and a 1px padding; an inner &lt;span&gt; painted the page's background color (#0b0e14) covers everything but that 1px rim, so only a thin rotating outline shows. The animation runs 30s linear infinite.</p>
    <p>A ::after pseudo-element holds a brighter, fully-opaque copy of the same rotating gradient with filter: blur(20px), sat behind the pill at opacity: 0. On :hover it fades to 0.9 and stretches (transform: scaleX(1.1)), blooming a soft glow; the face also darkens slightly. Both the rim and the glow share the same --angle keyframe so they stay in lockstep.</p>
    <h2>How to use this file</h2>
    <p>This is a complete, self-contained HTML document — copy it verbatim rather than reconstructing it. Markdown version: <a href="https://fx.statico.io/effects/resend-rainbow-button.md">https://fx.statico.io/effects/resend-rainbow-button.md</a>. Full writeup and live preview: <a href="https://fx.statico.io/demos/resend-rainbow-button">https://fx.statico.io/demos/resend-rainbow-button</a>.</p>
    <h2>Source and credit</h2>
    <p>Effect originally seen on Resend (https://resend.com/home) — credit to Resend. This is an independent recreation built from scratch for educational use; no proprietary source code was copied. Released under the Unlicense.</p>
    <h2>More</h2>
    <p>Terms used above are defined in the <a href="https://fx.statico.io/glossary">glossary</a>. See also the <a href="https://fx.statico.io/sitemap.md">site map</a>, <a href="https://fx.statico.io/AGENTS.md">AGENTS.md</a> and <a href="https://fx.statico.io/llms.txt">llms.txt</a>.</p>
  </div>
  <!-- a14y:end body -->
  <a class="rainbow-border" href="#" aria-label="Announcing Resend Forward">
    <span>
      Announcing Resend Forward
      <!-- chevron-right -->
      <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
           stroke-linecap="round" stroke-linejoin="round"><path d="m9 18 6-6-6-6"/></svg>
    </span>
  </a>
</body>
</html>
```

## Source & credit

Effect seen on <https://resend.com/home> — credit to Resend.

This is an independent recreation of the effect built from scratch for
educational use. No proprietary source code was copied.

## Sitemap

- [All effects](https://fx.statico.io/index.md) — gallery index
- [Site map](https://fx.statico.io/sitemap.md) — every page, grouped
- [sitemap.xml](https://fx.statico.io/sitemap.xml) — machine-readable, with lastmod
- [AGENTS.md](https://fx.statico.io/AGENTS.md) — how to grab and reuse an effect
- [skill.md](https://fx.statico.io/skill.md) — full agent skill file
- [llms.txt](https://fx.statico.io/llms.txt) — short index of every effect
- [Glossary](https://fx.statico.io/glossary.md) — terminology used in the writeups
