Hover✨ Premium

Shine Effect

A translucent white sheen crosses the element left to right in 0.5s on hover — one pass only, ::before pseudo-element, pure CSS.

CSSLight

Updated

This effect is part of Effect.Labs — 840 vanilla effects, some free, some premium. Hover has 48 effects, including 5 free. Explore the category →

3 usage examples

'Download brochure' CTA button — aluminium joinery manufacturer website — Shine Effect example 1

① 'Download brochure' CTA button — aluminium joinery manufacturer website

When300×56 px CTA button on indigo background; on hover the sheen passes once across the button.
WhyA CTA button that shimmers once on hover conveys premium quality without requiring a confirmed click.
Settings300×56 px button with 12 px corners; solid indigo background; slightly stronger sheen (rgba 0.3 at peak); hover zone within the capture ellipse.
Partner logo card for an independent pharmacy network — Shine Effect example 2

② Partner logo card for an independent pharmacy network

WhenPartner logos on a dark background; on hover a quick sheen crosses the logo like a moving light.
WhyA subtle sheen evokes an object held up to the light; it brings static logos to life without changing their layout.
Settings180×120 px cards in a grid; semi-transparent dark background; centred logos; targets on the capture ellipse.
Certification badge — trainer space for a real-estate e-learning platform — Shine Effect example 3

③ Certification badge — trainer space for a real-estate e-learning platform

WhenRectangular 'Certified' badge; on hover the light sheen crosses it, giving the impression of a metallic insignia.
WhyA certification badge mimics an engraved physical object; the sheen confirms its 'official' nature.
Settings200×80 px badge; grey metallic gradient background; bold text; 0.3 s duration to appear faster.

How it works

The .fx-0346-root wrapper centres a 200 px button. A ::before pseudo-element the same size as the button carries a horizontal gradient: transparent → rgba(255,255,255,0.2) → transparent — a narrow white highlight at its centre. At rest it is positioned at left: -100% (hidden to the left). On hover, left: 100% moves it off to the right. transition: left 0.5s animates this move: the sheen crosses the element once in a soft sweep, with no loop.

overflow: hidden on the element clips the sheen as it exits. The single-pass behaviour (no looping @keyframes) is intentional: the sheen should not animate continuously so it doesn't distract. Under reduced motion the move is suppressed and the pseudo-element stays hidden at left: -100%. :focus-visible triggers the same transit as hover.

Accessibility

  • Reduced motion: under prefers-reduced-motion: reduce, the transition is disabled and the pseudo-element stays hidden (left: -100%) even on hover. No motion, no sheen. The element keeps its resting appearance.
  • Keyboard: the element is a natively focusable <button>. :focus-visible triggers the sheen and adds a 2 px indigo outline. The translating sheen may be subtle — the outline serves as the main signal for keyboard users.
  • Touch: on touchscreens, a tap may not trigger the :hover transition on all browsers. The effect is a visual enhancement — functional interaction does not depend on it.
  • Decorative role: the sheen is purely cosmetic. No information is carried by the pseudo-element's motion. The element remains readable and usable without the effect.

Browser compatibility

Pure CSS. Properties: ::before, left (transition), overflow: hidden, :focus-visible. Verified in Chromium and Firefox: sheen visible, two independent copies, 0 errors. The left transition triggers a repaint — for better performance, replace with transform: translateX (see FAQ).

Chrome 86+✓ Full (measured)
Firefox 85+✓ Full (measured)
Safari 15.4+✓ Full (:focus-visible)
Edge 86+✓ Full (Chromium engine)
Mobile iOS 15.4+✓ Full
Android Chrome 86+✓ Full (measured)

Without :focus-visible (before 2021), keyboard focus may trigger the sheen via :focus only if the browser supports it — the effect may also appear on click in some browsers.

The code

HTML structure to paste into your page (the CSS + JS come with your purchase):

index.html — structure
<div class="fx-0346-root">
  <button class="shn-box shn-shine" type="button">
    <span>Your text</span>
  </button>
</div>

One-time payment, no subscription — the code is yours forever

Customize

Options passed to the API or data-* attributes:

Option / propertyDefaultEffect
Sheen intensity (CSS — rgba(255,255,255,0.2)) 20% white 0.1 is nearly invisible; 0.4 is very bright. On light backgrounds, reduce opacity or use a colour other than pure white.
Duration (CSS — 0.5s) 0.5 s 0.25 s creates a quick flash; 0.8 s a slow sweep.
Sheen width (CSS — width: 100% on ::before) 100% of element Reducing to 50% creates a narrower, more visible highlight. Adjust the gradient to keep the white peak at the centre.
Performance (replace left with transform) left transition (repaint) Replace left: -100%/100% with transform: translateX(-200%)/translateX(200%) on ::before to use the compositor layer and avoid repaint — especially useful when multiple elements animate simultaneously.
Repeat (add a looping @keyframes) one pass on hover For a continuous sheen, replace the transition with animation: shn-loop 2s linear infinite with a keyframe animating left from -100% to 100%. Enable the animation on hover and disable it on leave.

FAQ

The sheen only passes once because the left: -100% → 100% animation ends off-screen. For multiple passes, use a @keyframes on translateX with iteration-count: 2 or infinite, triggered on :hover.
Yes, by design: overflow: hidden on the element clips the sheen as soon as it exits its bounds. Remove this property if you want the sheen to overflow (e.g. on an image without a strict frame).
Yes. Tilt the gradient in ::before: background: linear-gradient(60deg, transparent, rgba(255,255,255,0.2), transparent), and increase the pseudo-element width to 150–200% so the sheen fully crosses the element.