Let's make that animated gradient text effect with scoped custom properties and background-clip


![Jhey Tompkins](https://web.dev/images/authors/jheyy.jpg) Jhey Tompkins [X](https://twitter.com/jh3yy) [GitHub](https://github.com/jh3y) [LinkedIn](https://www.linkedin.com/in/jheytompkins) [Mastodon](https://front-end.social/@jhey) [Homepage](https://jhey.dev/links)

<br />

Hop over to [CodePen](https://pen.new) and create a new pen.

Create the markup for your text. Let's use a header with the word "Speedy":

    <h1 class="boujee-text">Hello!</h1>

Then, let's give our `body` a darker `background-color`:

    body {
      display: grid;
      place-items: center;
      min-height: 100vh;
      background: hsl(0 0% 20%);
    }

Bump up the `font-size` on our text. Use `clamp` to make it responsive:

    .boujee-text {
      font-size: clamp(3rem, 25vmin, 8rem);
    }

Create two custom properties for the colors we're going to use. Apply a `linear-gradient` to the `background` using those colors and rotate it by 90 degrees:

    .boujee-text {
      --color-one: hsl(15 90% 55%);
      --color-two: hsl(40 95% 55%);
      font-size: clamp(3rem, 25vmin, 8rem);
      background: linear-gradient(
                    90deg,
                    var(--color-one),
                    var(--color-two),
                    var(--color-one)
                  ) 0 0 / 100% 100%;
    }

Create a custom property that you can use for the horizontal background size. Use it for `background-size-x`:

    .boujee-text {
      --bg-size: 400%;
      --color-one: hsl(15 90% 55%);
      --color-two: hsl(40 95% 55%);
      font-size: clamp(3rem, 25vmin, 8rem);
      background: linear-gradient(
                    90deg,
                    var(--color-one),
                    var(--color-two),
                    var(--color-one)
                  ) 0 0 / var(--bg-size) 100%;
    }

To clip the background to the text set the `color` to `transparent`, and set `background-clip: text`:

    .boujee-text {
      --bg-size: 400%;
      --color-one: hsl(15 90% 55%);
      --color-two: hsl(40 95% 55%);
      font-size: clamp(3rem, 25vmin, 8rem);
      background: linear-gradient(
                    90deg,
                    var(--color-one),
                    var(--color-two),
                    var(--color-one)
                  ) 0 0 / var(--bg-size) 100%;
      color: transparent;
      -webkit-background-clip: text;
      background-clip: text;
    }

> [!NOTE]
> **Note:** The `background-clip` property needs prefixing in some browsers as `-webkit-background-clip`.

At this point, you could leave it there and experiment with the `background-position` and the gradient used in the `background-image`. Or, you could animate that gradient across your text. First, define a keyframe for the animation. This will use the `--bg-size` custom property you defined earlier. A good example of scoped custom properties making maintenance easier for you.

    @keyframes move-bg {
      to {
        background-position: var(--bg-size) 0;
      }
    }

Then apply the animation using `animation`:

    .boujee-text {
      --bg-size: 400%;
      --color-one: hsl(15 90% 55%);
      --color-two: hsl(40 95% 55%);
      font-size: clamp(3rem, 25vmin, 8rem);
      background: linear-gradient(
                    90deg,
                    var(--color-one),
                    var(--color-two),
                    var(--color-one)
                  ) 0 0 / var(--bg-size) 100%;
      color: transparent;
      background-clip: text;
      -webkit-background-clip: text;
      animation: move-bg 8s infinite linear;
    }

To take this further, you can wrap your animation code in a media query to respect your user's preferences for motion:

    @media (prefers-reduced-motion: no-preference) {
      .boujee-text {
        animation: move-bg 8s linear infinite;
      }
      @keyframes move-bg {
        to {
          background-position: var(--bg-size) 0;
        }
      }
    }

<iframe allow="camera; clipboard-read; clipboard-write; encrypted-media; geolocation; microphone; midi;" loading="lazy" src="https://codepen.io/web-dot-dev/embed/vYrGPNE?height=300&amp;theme-id=dark&amp;default-tab=result&amp;editable=true" style="height: 100%; width: 100%; border: 0;" title="Pen vYrGPNE by web-dot-dev on Codepen"></iframe>

Done! 🎉 You've created some animated gradient text with CSS using scoped custom properties and `background-clip`.

Here's this tip in its speedy video form! ⚡️

Prefer this in [tweet form](https://twitter.com/jh3yy/status/1517629642064150529)? 🐦

Stay Awesome!