20 CSS Animated Buttons08 / 20

Pure CSSMIT licensed

CSS Shine Sweep Hover Button

A metallic light-streak sweeps diagonally across the button surface on hover, simulating a premium gloss reflection using a CSS pseudo-element gradient and translate animation.

Published

Live Demo
Try it

The code

<div class="ab-08">
  <p class="ab-08__label">Hover over the buttons</p>
  <div class="ab-08__row">
    <button class="ab-08__btn ab-08__btn--dark">Pro Features</button>
    <button class="ab-08__btn ab-08__btn--gold">Upgrade Now</button>
    <button class="ab-08__btn ab-08__btn--violet">Get Premium</button>
  </div>
</div>
.ab-08,
.ab-08 *,
.ab-08 *::before,
.ab-08 *::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

.ab-08 ::selection {
  background: #1e293b;
  color: #fff;
}

.ab-08 {
  font-family: system-ui,sans-serif;
  background: #f1f5f9;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2rem;
  padding: 2rem;
}

.ab-08__label {
  font-size: .78rem;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: #64748b;
}

.ab-08__row {
  display: flex;
  gap: 1rem;
  flex-wrap: wrap;
  justify-content: center;
}

.ab-08__btn {
  position: relative;
  overflow: hidden;
  padding: .85rem 2.2rem;
  font-size: .95rem;
  font-weight: 700;
  border: none;
  border-radius: 10px;
  cursor: pointer;
  outline: none;
  letter-spacing: .04em;
  transition: filter .2s,transform .15s;
}

.ab-08__btn--dark {
  background: #1e293b;
  color: #e2e8f0;
}

.ab-08__btn--gold {
  background: linear-gradient(135deg,#b45309,#d97706,#fbbf24);
  color: #fff;
}

.ab-08__btn--violet {
  background: linear-gradient(135deg,#4c1d95,#7c3aed,#a78bfa);
  color: #fff;
}

.ab-08__btn:hover {
  filter: brightness(1.1);
  transform: translateY(-2px);
}

.ab-08__btn:active {
  transform: translateY(0);
  filter: brightness(.95);
}

.ab-08__btn::before {
  content: '';
  position: absolute;
  top: -10%;
  left: -20%;
  width: 60%;
  height: 120%;
  background: linear-gradient(105deg,transparent 30%,rgba(255,255,255,.55) 50%,transparent 70%);
  transform: translateX(-100%) skewX(-15deg);
  pointer-events: none;
}

.ab-08__btn:hover::before {
  animation: ab-08-shine .55s ease-in-out forwards;
}

@keyframes ab-08-shine {
  0% {
    transform: translateX(-100%) skewX(-15deg);
  }

  100% {
    transform: translateX(400%) skewX(-15deg);
  }
}

@media (prefers-reduced-motion: reduce) {
  .ab-08__btn:hover::before {
    animation: none;
  }
}
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 Animated Button 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: CSS Shine Sweep Hover Button
Source: https://codefronts.com/motion/css-animated-buttons/css-shine-sweep-hover-button/

A metallic light-streak sweeps diagonally across the button surface on hover, simulating a premium gloss reflection using a CSS pseudo-element gradient and translate animation.
## HTML
```html
<div class="ab-08">
  <p class="ab-08__label">Hover over the buttons</p>
  <div class="ab-08__row">
    <button class="ab-08__btn ab-08__btn--dark">Pro Features</button>
    <button class="ab-08__btn ab-08__btn--gold">Upgrade Now</button>
    <button class="ab-08__btn ab-08__btn--violet">Get Premium</button>
  </div>
</div>
```
## CSS
```css
.ab-08,
.ab-08 *,
.ab-08 *::before,
.ab-08 *::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

.ab-08 ::selection {
  background: #1e293b;
  color: #fff;
}

.ab-08 {
  font-family: system-ui,sans-serif;
  background: #f1f5f9;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2rem;
  padding: 2rem;
}

.ab-08__label {
  font-size: .78rem;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: #64748b;
}

.ab-08__row {
  display: flex;
  gap: 1rem;
  flex-wrap: wrap;
  justify-content: center;
}

.ab-08__btn {
  position: relative;
  overflow: hidden;
  padding: .85rem 2.2rem;
  font-size: .95rem;
  font-weight: 700;
  border: none;
  border-radius: 10px;
  cursor: pointer;
  outline: none;
  letter-spacing: .04em;
  transition: filter .2s,transform .15s;
}

.ab-08__btn--dark {
  background: #1e293b;
  color: #e2e8f0;
}

.ab-08__btn--gold {
  background: linear-gradient(135deg,#b45309,#d97706,#fbbf24);
  color: #fff;
}

.ab-08__btn--violet {
  background: linear-gradient(135deg,#4c1d95,#7c3aed,#a78bfa);
  color: #fff;
}

.ab-08__btn:hover {
  filter: brightness(1.1);
  transform: translateY(-2px);
}

.ab-08__btn:active {
  transform: translateY(0);
  filter: brightness(.95);
}

.ab-08__btn::before {
  content: '';
  position: absolute;
  top: -10%;
  left: -20%;
  width: 60%;
  height: 120%;
  background: linear-gradient(105deg,transparent 30%,rgba(255,255,255,.55) 50%,transparent 70%);
  transform: translateX(-100%) skewX(-15deg);
  pointer-events: none;
}

.ab-08__btn:hover::before {
  animation: ab-08-shine .55s ease-in-out forwards;
}

@keyframes ab-08-shine {
  0% {
    transform: translateX(-100%) skewX(-15deg);
  }

  100% {
    transform: translateX(400%) skewX(-15deg);
  }
}

@media (prefers-reduced-motion: reduce) {
  .ab-08__btn:hover::before {
    animation: none;
  }
}
```

How this works

The shine is a ::before pseudo-element carrying a linear-gradient(105deg, transparent 30%, rgba(255,255,255,.5) 50%, transparent 70%) — a narrow bright band between two transparent regions. It starts positioned off the left edge via transform: translateX(-100%) skewX(-15deg). On hover, a @keyframes ab-08-shine animation translates it to translateX(300%) skewX(-15deg), sweeping it across the button face in one smooth pass. The skewX gives the streak a diagonal cut that reads as natural glancing light.

overflow: hidden on the button clips the streak as it enters and exits, keeping the effect tight. animation-fill-mode: forwards holds the streak off-screen after completion so it doesn't snap back visibly. A second hover on the button re-triggers the animation by adding a CSS class toggle — in the Pure CSS version the animation is retriggered naturally each time the cursor re-enters because :hover resets the state cleanly.

Make it yours

  • Widen the shine streak by increasing the gradient midpoint range from 30% … 70% to 20% … 80% for a broader flash.
  • Change the tilt angle by adjusting skewX(-15deg) — a value of -30deg gives a steeper, more dramatic diagonal cut.
  • Use a gold or rose tinted shine by replacing rgba(255,255,255,.5) with rgba(255,215,100,.5) for a premium metallic feel.
  • Delay the sweep on page load by adding animation-delay: 1s directly on the button's ::before to catch the user's attention after they've settled.
  • Chain multiple sweeps by setting animation-iteration-count: 3 with an animation-delay between iterations using animation shorthand timing.

Gotchas — read before shipping

  • The :hover restart trick works in pure CSS but is not pixel-perfect — rapid mouse oscillation at the button edge can make the animation restart mid-sweep; add a JS class toggle for fine control.
  • overflow: hidden clips the streak but also any box-shadow on the button — wrap the button in a div that carries the shadow if you need both effects simultaneously.
  • On iOS, :hover is triggered by a tap and stays active until another tap elsewhere — the shine will remain triggered rather than play-and-reset; acceptable behaviour on touch devices.

Browser support

ChromeSafariFirefoxEdge
26+9+16+26+

Uses only CSS animations and gradients; works in all modern browsers without prefixes.

Techniques used in this demo

Search CodeFronts

Loading…