30 CSS Text Hover Effects08 / 30

CSS onlyMIT licensed

Shimmer / Metallic Shine Effect

Gold you can grade: a members-card wordmark set in a five-stop metallic gradient (shadow gold → base → near-white highlight band → base → shadow) clipped into the glyphs, with the light sweep done by sliding background-position across a 250%-wide canvas on hover — the gradient never changes, the LIGHT moves. The eyebrow line runs a slow 6s ambient shimmer so the card glints even untouched, the way foil does under ceiling light; the big mark saves its full sweep for your cursor.

Published

Live Demo
Try it

The code

<section class="cth-08" aria-label="Metallic shimmer text demo">
  <div class="cth-08__stage">
    <a class="cth-08__card" href="#cth08-top" id="cth08-top">
      <p class="cth-08__eyebrow"><span class="cth-08__gold cth-08__gold--ambient">Est. MMXXVI &middot; by invitation</span></p>
      <h1 class="cth-08__mark"><span class="cth-08__gold cth-08__gold--sweep">AURUM<br>RESERVE</span></h1>
      <div class="cth-08__foot">
        <span class="cth-08__tier">Founding member &mdash; No. 047</span>
        <span class="cth-08__price"><b class="cth-08__gold cth-08__gold--sweep">$890</b><small>/year</small></span>
      </div>
      <p class="cth-08__hint">Hover the card: the gradient never changes &mdash; <code>background-position</code> slides the glint band through the glyphs.</p>
    </a>
  </div>
</section>
.cth-08,
.cth-08 *,
.cth-08 *::before,
.cth-08 *::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

.cth-08 {
  --bg: oklch(0.15 0.008 70);
  --card: oklch(0.19 0.01 75);
  --line: oklch(0.34 0.03 85);
  --mut: oklch(0.62 0.03 80);
  --gold-1: oklch(0.88 0.09 92);
  --gold-2: oklch(0.72 0.11 85);
  --gold-3: oklch(0.5 0.09 78);
  font-family: Georgia,'Times New Roman',serif;
  color: oklch(0.9 0.02 85);
}

.cth-08__stage {
  width: 100%;
  min-height: 100vh;
  min-height: 100svh;
  display: grid;
  place-items: center;
  background: radial-gradient(100% 80% at 50% 0%,oklch(0.19 0.012 75),var(--bg) 70%);
  padding: clamp(20px,4vw,56px);
  container: cth08/inline-size;
}

.cth-08__card {
  display: flex;
  flex-direction: column;
  gap: clamp(18px,3.4cqi,30px);
  width: min(100%,560px);
  padding: clamp(26px,5cqi,46px);
  background: linear-gradient(160deg,var(--card),oklch(0.16 0.009 72));
  border: 1px solid var(--line);
  border-radius: 20px;
  text-decoration: none;
  color: inherit;
  box-shadow: 0 30px 80px oklch(0.05 0.01 70/.6),inset 0 1px 0 oklch(1 0 0/.06);
  transition: border-color .5s ease,translate .5s cubic-bezier(.22,1,.36,1);
}

.cth-08__card:hover,
.cth-08__card:focus-visible {
  border-color: color-mix(in oklch,var(--gold-2) 55%,var(--line));
  translate: 0 -4px;
}

.cth-08__card:focus-visible {
  outline: 2px solid var(--gold-1);
  outline-offset: 4px;
}

.cth-08__gold {
  background-image: linear-gradient(105deg,var(--gold-3) 0%,var(--gold-2) 34%,oklch(0.97 0.05 95) 49%,var(--gold-2) 64%,var(--gold-3) 100%);
  background-size: 250% 100%;
  background-position: 97% 0;
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

.cth-08__gold--sweep {
  transition: background-position 1.1s cubic-bezier(.25,.66,.15,1);
}

.cth-08__card:hover .cth-08__gold--sweep,
.cth-08__card:focus-visible .cth-08__gold--sweep {
  background-position: 3% 0;
}

.cth-08__gold--ambient {
  animation: cth08-glint 6s ease-in-out infinite;
}

@keyframes cth08-glint {
  0%,
    100% {
    background-position: 97% 0;
  }

  50% {
    background-position: 3% 0;
  }
}

.cth-08__eyebrow {
  font-size: 12.5px;
  letter-spacing: .3em;
  text-transform: uppercase;
}

.cth-08__mark {
  font-size: clamp(44px,9.4cqi,84px);
  font-weight: 700;
  letter-spacing: .045em;
  line-height: 1.04;
  filter: drop-shadow(0 3px 10px oklch(0.05 0.01 70/.7));
}

.cth-08__foot {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 14px;
  border-top: 1px solid var(--line);
  padding-top: clamp(14px,2.6cqi,20px);
}

.cth-08__tier {
  font-size: 12.5px;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--mut);
}

.cth-08__price {
  display: flex;
  align-items: baseline;
  gap: 5px;
}

.cth-08__price b {
  font-size: clamp(24px,4cqi,32px);
  font-weight: 700;
}

.cth-08__price small {
  font-size: 12px;
  color: var(--mut);
  font-family: 'Segoe UI',system-ui,sans-serif;
}

.cth-08__hint {
  font-size: 12px;
  line-height: 1.7;
  color: var(--mut);
  font-family: 'Segoe UI',system-ui,sans-serif;
}

.cth-08__hint code {
  font-family: ui-monospace,Menlo,Consolas,monospace;
  font-size: .92em;
  background: oklch(0.26 0.015 75);
  padding: 1px 6px;
  border-radius: 4px;
  color: var(--gold-1);
}

@media (prefers-reduced-motion: reduce) {
  .cth-08 * {
    animation: none !important;
    transition-duration: .01ms !important;
  }
}
Paste this into ChatGPT, Claude, Cursor, or any coding assistant. The block below is pre-framed with everything the AI needs to integrate this demo into your project — markup, styles, scoping notes, and the source URL. Hit Copy and paste straight into your chat.
Here's a working CSS Text Hover Effect from CodeFronts. Use it as-is or adapt to your framework. All classes are scoped under a unique prefix so the code won't collide with your existing styles. MIT licensed.
Demo: Shimmer / Metallic Shine Effect
Source: https://codefronts.com/motion/css-text-hover-effects/shimmer-metallic-shine-effect/

Gold you can grade: a members-card wordmark set in a five-stop metallic gradient (shadow gold → base → near-white highlight band → base → shadow) clipped into the glyphs, with the light sweep done by sliding background-position across a 250%-wide canvas on hover — the gradient never changes, the LIGHT moves. The eyebrow line runs a slow 6s ambient shimmer so the card glints even untouched, the way foil does under ceiling light; the big mark saves its full sweep for your cursor.
## HTML
```html
<section class="cth-08" aria-label="Metallic shimmer text demo">
  <div class="cth-08__stage">
    <a class="cth-08__card" href="#cth08-top" id="cth08-top">
      <p class="cth-08__eyebrow"><span class="cth-08__gold cth-08__gold--ambient">Est. MMXXVI &middot; by invitation</span></p>
      <h1 class="cth-08__mark"><span class="cth-08__gold cth-08__gold--sweep">AURUM<br>RESERVE</span></h1>
      <div class="cth-08__foot">
        <span class="cth-08__tier">Founding member &mdash; No. 047</span>
        <span class="cth-08__price"><b class="cth-08__gold cth-08__gold--sweep">$890</b><small>/year</small></span>
      </div>
      <p class="cth-08__hint">Hover the card: the gradient never changes &mdash; <code>background-position</code> slides the glint band through the glyphs.</p>
    </a>
  </div>
</section>
```
## CSS
```css
.cth-08,
.cth-08 *,
.cth-08 *::before,
.cth-08 *::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

.cth-08 {
  --bg: oklch(0.15 0.008 70);
  --card: oklch(0.19 0.01 75);
  --line: oklch(0.34 0.03 85);
  --mut: oklch(0.62 0.03 80);
  --gold-1: oklch(0.88 0.09 92);
  --gold-2: oklch(0.72 0.11 85);
  --gold-3: oklch(0.5 0.09 78);
  font-family: Georgia,'Times New Roman',serif;
  color: oklch(0.9 0.02 85);
}

.cth-08__stage {
  width: 100%;
  min-height: 100vh;
  min-height: 100svh;
  display: grid;
  place-items: center;
  background: radial-gradient(100% 80% at 50% 0%,oklch(0.19 0.012 75),var(--bg) 70%);
  padding: clamp(20px,4vw,56px);
  container: cth08/inline-size;
}

.cth-08__card {
  display: flex;
  flex-direction: column;
  gap: clamp(18px,3.4cqi,30px);
  width: min(100%,560px);
  padding: clamp(26px,5cqi,46px);
  background: linear-gradient(160deg,var(--card),oklch(0.16 0.009 72));
  border: 1px solid var(--line);
  border-radius: 20px;
  text-decoration: none;
  color: inherit;
  box-shadow: 0 30px 80px oklch(0.05 0.01 70/.6),inset 0 1px 0 oklch(1 0 0/.06);
  transition: border-color .5s ease,translate .5s cubic-bezier(.22,1,.36,1);
}

.cth-08__card:hover,
.cth-08__card:focus-visible {
  border-color: color-mix(in oklch,var(--gold-2) 55%,var(--line));
  translate: 0 -4px;
}

.cth-08__card:focus-visible {
  outline: 2px solid var(--gold-1);
  outline-offset: 4px;
}

.cth-08__gold {
  background-image: linear-gradient(105deg,var(--gold-3) 0%,var(--gold-2) 34%,oklch(0.97 0.05 95) 49%,var(--gold-2) 64%,var(--gold-3) 100%);
  background-size: 250% 100%;
  background-position: 97% 0;
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

.cth-08__gold--sweep {
  transition: background-position 1.1s cubic-bezier(.25,.66,.15,1);
}

.cth-08__card:hover .cth-08__gold--sweep,
.cth-08__card:focus-visible .cth-08__gold--sweep {
  background-position: 3% 0;
}

.cth-08__gold--ambient {
  animation: cth08-glint 6s ease-in-out infinite;
}

@keyframes cth08-glint {
  0%,
    100% {
    background-position: 97% 0;
  }

  50% {
    background-position: 3% 0;
  }
}

.cth-08__eyebrow {
  font-size: 12.5px;
  letter-spacing: .3em;
  text-transform: uppercase;
}

.cth-08__mark {
  font-size: clamp(44px,9.4cqi,84px);
  font-weight: 700;
  letter-spacing: .045em;
  line-height: 1.04;
  filter: drop-shadow(0 3px 10px oklch(0.05 0.01 70/.7));
}

.cth-08__foot {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 14px;
  border-top: 1px solid var(--line);
  padding-top: clamp(14px,2.6cqi,20px);
}

.cth-08__tier {
  font-size: 12.5px;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--mut);
}

.cth-08__price {
  display: flex;
  align-items: baseline;
  gap: 5px;
}

.cth-08__price b {
  font-size: clamp(24px,4cqi,32px);
  font-weight: 700;
}

.cth-08__price small {
  font-size: 12px;
  color: var(--mut);
  font-family: 'Segoe UI',system-ui,sans-serif;
}

.cth-08__hint {
  font-size: 12px;
  line-height: 1.7;
  color: var(--mut);
  font-family: 'Segoe UI',system-ui,sans-serif;
}

.cth-08__hint code {
  font-family: ui-monospace,Menlo,Consolas,monospace;
  font-size: .92em;
  background: oklch(0.26 0.015 75);
  padding: 1px 6px;
  border-radius: 4px;
  color: var(--gold-1);
}

@media (prefers-reduced-motion: reduce) {
  .cth-08 * {
    animation: none !important;
    transition-duration: .01ms !important;
  }
}
```

How this works

Metal is a gradient with a highlight band; shine is that band traveling. Make the background canvas wider than the text and animate only its position:

.gold{
  background-image:linear-gradient(105deg,
    var(--gold-3) 0%,  var(--gold-2) 34%,
    oklch(0.97 0.05 95) 49%,           /* the glint band */
    var(--gold-2) 64%,  var(--gold-3) 100%);
  background-size:250% 100%;
  background-position:97% 0;           /* glint parked right  */
  -webkit-background-clip:text; background-clip:text;
  color:transparent;
  transition:background-position 1.1s cubic-bezier(.25,.66,.15,1); }
.card:hover .gold{ background-position:3% 0; }

Because background-size is 250%, position values map onto a long runway: at 97% the near-white band waits off the right edge of the glyphs; hover glides it through every letterform to the far left. One property transitions — cheap, buttery, and it reverses gracefully when the cursor leaves (the light walks back, which reads as the card tilting the other way).

Two grades of shimmer are the taste decision documented here: the AMBIENT one (eyebrow) is a 6s infinite keyframe crossing a mostly-flat gradient — jewelry-counter light, ignorable; the EARNED one (wordmark) only answers the cursor. Put the infinite loop on your biggest type and you've built a Vegas slot machine; the hierarchy is the design. Serif matters too — thick-thin stroke contrast gives the highlight band edges to catch, which is why this is Georgia and not a geometric sans.

Make it yours

  • Alloy swap: silver = same five stops with chroma ~0.01 around hue 260; rose gold = hue 35 at low chroma; copper = hue 50, darker base. Only the tokens change.
  • Sweep angle: 105deg mimics overhead light; 75deg feels handheld. Keep the two shimmer layers (ambient + hover) on the same angle or the light sources contradict.
  • Speed = material: 1.1s reads as heavy foil; 400ms reads as plastic. If the brand is 'quiet luxury', go slower, never faster.
  • One-shot sparkle: to glint exactly once on hover (no reverse), move the sweep into a keyframe with fill-mode:forwards and trigger it on :hover instead of transitioning.

Gotchas — read before shipping

  • Both clip declarations (-webkit- first) or Chromium paints the gradient as a rectangle; and remember color:transparent, or the text color covers your metal entirely.
  • text-shadow paints OVER clipped backgrounds — depth must come from filter:drop-shadow() (used here), which respects the glyph alpha instead of stamping a rectangle.
  • A highlight band wider than ~18% of the gradient stops reading as light and starts reading as a second color — keep the glint narrow.
  • Infinite shimmer on large clipped text re-rasters the gradient every frame; scope loops to small type (the eyebrow) and let big type animate only on hover.

Browser support

ChromeSafariFirefoxEdge
111+16.4+113+111+

background-clip:text sweeps work in every 2020+ engine (prefixed); floor reflects oklch()/color-mix() tokens — with hex golds this runs basically anywhere.

Techniques used in this demo

Search CodeFronts

Loading…