30 CSS Hover Effects 09 / 30
CSS Shimmer Shine Button Hover Effect
Five light-streak and shimmer button effects — diagonal gloss swipe, radial spotlight, frosted edge shimmer, holographic foil, and full-button shimmer wash — using pseudo-element gradients animated on hover to simulate a reflective material surface.
This is a full-page demo — interact inside the frame above, or open it in the playground for the full-screen experience.
The code
<div class="hv-09">
<div class="hv-09__stack">
<div class="hv-09__row">
<button class="hv-09__btn hv-09__btn--diagonal">Diagonal Gloss</button>
<span class="hv-09__label">translateX streak</span>
</div>
<div class="hv-09__row">
<button class="hv-09__btn hv-09__btn--radial">Radial Spotlight</button>
<span class="hv-09__label">radial-gradient reveal</span>
</div>
<div class="hv-09__row">
<button class="hv-09__btn hv-09__btn--frost">Frosted Edge</button>
<span class="hv-09__label">edge-shimmer effect</span>
</div>
<div class="hv-09__row">
<button class="hv-09__btn hv-09__btn--holo">Holographic Foil</button>
<span class="hv-09__label">conic-gradient holo</span>
</div>
<div class="hv-09__row">
<button class="hv-09__btn hv-09__btn--wash">Shimmer Wash</button>
<span class="hv-09__label">full-button wave</span>
</div>
</div>
</div> <div class="hv-09">
<div class="hv-09__stack">
<div class="hv-09__row">
<button class="hv-09__btn hv-09__btn--diagonal">Diagonal Gloss</button>
<span class="hv-09__label">translateX streak</span>
</div>
<div class="hv-09__row">
<button class="hv-09__btn hv-09__btn--radial">Radial Spotlight</button>
<span class="hv-09__label">radial-gradient reveal</span>
</div>
<div class="hv-09__row">
<button class="hv-09__btn hv-09__btn--frost">Frosted Edge</button>
<span class="hv-09__label">edge-shimmer effect</span>
</div>
<div class="hv-09__row">
<button class="hv-09__btn hv-09__btn--holo">Holographic Foil</button>
<span class="hv-09__label">conic-gradient holo</span>
</div>
<div class="hv-09__row">
<button class="hv-09__btn hv-09__btn--wash">Shimmer Wash</button>
<span class="hv-09__label">full-button wave</span>
</div>
</div>
</div>.hv-09,.hv-09 *,.hv-09 *::before,.hv-09 *::after{box-sizing:border-box;margin:0;padding:0}
.hv-09 ::selection{background:#6366f1;color:#fff}
.hv-09{
--bg:#07070f;
--text:#e0e0ff;
--dim:#4b5563;
--indigo:#6366f1;
--violet:#8b5cf6;
--blue:#3b82f6;
--sky:#0ea5e9;
font-family:'Segoe UI',system-ui,sans-serif;
background:var(--bg);
min-height:100vh;
display:flex;align-items:center;justify-content:center;
padding:60px 24px;
}
.hv-09__stack{
display:flex;flex-direction:column;gap:20px;
width:min(640px,100%);
}
.hv-09__row{
display:flex;align-items:center;justify-content:space-between;
gap:24px;padding:24px 36px;
background:rgba(255,255,255,.025);
border:1px solid rgba(255,255,255,.07);
border-radius:12px;
}
.hv-09__label{font-size:11px;letter-spacing:.12em;text-transform:uppercase;color:var(--dim);white-space:nowrap;flex-shrink:0}
/* shared btn */
.hv-09__btn{
position:relative;overflow:hidden;
padding:13px 36px;border:none;
font-size:.95rem;font-weight:600;letter-spacing:.05em;
cursor:pointer;border-radius:8px;flex-shrink:0;
}
.hv-09__btn::before{content:'';position:absolute;pointer-events:none}
/* 1 — diagonal gloss */
.hv-09__btn--diagonal{
background:var(--indigo);color:#fff;
}
.hv-09__btn--diagonal::before{
top:0;left:-75%;width:75%;height:100%;
background:linear-gradient(105deg,transparent 0%,rgba(255,255,255,.7) 50%,transparent 100%);
transition:left .7s cubic-bezier(.4,0,.2,1);
}
.hv-09__btn--diagonal:hover::before{left:125%}
/* 2 — radial spotlight */
.hv-09__btn--radial{
background:var(--violet);color:#fff;
}
.hv-09__btn--radial::before{
inset:0;
background:radial-gradient(circle at 50% 50%,rgba(255,255,255,.5) 0%,transparent 65%);
opacity:0;transition:opacity .4s;
}
.hv-09__btn--radial:hover::before{opacity:1}
/* 3 — frosted edge */
.hv-09__btn--frost{
background:transparent;color:var(--blue);
border:2px solid var(--blue);
transition:background .4s ease,color .4s ease,box-shadow .4s ease;
}
.hv-09__btn--frost::before{
top:0;left:0;width:60%;height:100%;
background:linear-gradient(90deg,rgba(59,130,246,.55),transparent);
transform:translateX(-100%);
transition:transform .5s ease;
}
.hv-09__btn--frost:hover{box-shadow:0 0 24px rgba(59,130,246,.35)}
.hv-09__btn--frost:hover::before{transform:translateX(0)}
.hv-09__btn--frost::after{
content:'';position:absolute;top:0;right:0;width:60%;height:100%;
background:linear-gradient(270deg,rgba(59,130,246,.55),transparent);
transform:translateX(100%);
transition:transform .5s ease;
pointer-events:none;
}
.hv-09__btn--frost:hover::after{transform:translateX(0)}
/* 4 — holographic foil */
.hv-09__btn--holo{
background:conic-gradient(from 0deg,#6366f1,#8b5cf6,#ec4899,#f59e0b,#10b981,#06b6d4,#6366f1);
background-size:200% 200%;
background-position:0% 50%;
color:#fff;
transition:background-position .6s,filter .4s;
}
.hv-09__btn--holo:hover{
background-position:100% 50%;
filter:brightness(1.2) saturate(1.3);
}
/* 5 — shimmer wash */
.hv-09__btn--wash{
background:linear-gradient(135deg,var(--sky),var(--indigo));
color:#fff;
}
.hv-09__btn--wash::before{
top:0;left:-100%;width:100%;height:100%;
background:linear-gradient(
90deg,
transparent 0%,
rgba(255,255,255,.6) 50%,
transparent 100%
);
}
.hv-09__btn--wash:hover::before{
animation:hv-09-wash .9s ease-in-out forwards;
}
@keyframes hv-09-wash{
0%{left:-100%}
100%{left:100%}
}
@media(max-width:500px){.hv-09__row{flex-direction:column;align-items:flex-start}}
@media(prefers-reduced-motion:reduce){
.hv-09__btn::before,.hv-09__btn::after{transition:none!important;animation:none!important}
} .hv-09,.hv-09 *,.hv-09 *::before,.hv-09 *::after{box-sizing:border-box;margin:0;padding:0}
.hv-09 ::selection{background:#6366f1;color:#fff}
.hv-09{
--bg:#07070f;
--text:#e0e0ff;
--dim:#4b5563;
--indigo:#6366f1;
--violet:#8b5cf6;
--blue:#3b82f6;
--sky:#0ea5e9;
font-family:'Segoe UI',system-ui,sans-serif;
background:var(--bg);
min-height:100vh;
display:flex;align-items:center;justify-content:center;
padding:60px 24px;
}
.hv-09__stack{
display:flex;flex-direction:column;gap:20px;
width:min(640px,100%);
}
.hv-09__row{
display:flex;align-items:center;justify-content:space-between;
gap:24px;padding:24px 36px;
background:rgba(255,255,255,.025);
border:1px solid rgba(255,255,255,.07);
border-radius:12px;
}
.hv-09__label{font-size:11px;letter-spacing:.12em;text-transform:uppercase;color:var(--dim);white-space:nowrap;flex-shrink:0}
/* shared btn */
.hv-09__btn{
position:relative;overflow:hidden;
padding:13px 36px;border:none;
font-size:.95rem;font-weight:600;letter-spacing:.05em;
cursor:pointer;border-radius:8px;flex-shrink:0;
}
.hv-09__btn::before{content:'';position:absolute;pointer-events:none}
/* 1 — diagonal gloss */
.hv-09__btn--diagonal{
background:var(--indigo);color:#fff;
}
.hv-09__btn--diagonal::before{
top:0;left:-75%;width:75%;height:100%;
background:linear-gradient(105deg,transparent 0%,rgba(255,255,255,.7) 50%,transparent 100%);
transition:left .7s cubic-bezier(.4,0,.2,1);
}
.hv-09__btn--diagonal:hover::before{left:125%}
/* 2 — radial spotlight */
.hv-09__btn--radial{
background:var(--violet);color:#fff;
}
.hv-09__btn--radial::before{
inset:0;
background:radial-gradient(circle at 50% 50%,rgba(255,255,255,.5) 0%,transparent 65%);
opacity:0;transition:opacity .4s;
}
.hv-09__btn--radial:hover::before{opacity:1}
/* 3 — frosted edge */
.hv-09__btn--frost{
background:transparent;color:var(--blue);
border:2px solid var(--blue);
transition:background .4s ease,color .4s ease,box-shadow .4s ease;
}
.hv-09__btn--frost::before{
top:0;left:0;width:60%;height:100%;
background:linear-gradient(90deg,rgba(59,130,246,.55),transparent);
transform:translateX(-100%);
transition:transform .5s ease;
}
.hv-09__btn--frost:hover{box-shadow:0 0 24px rgba(59,130,246,.35)}
.hv-09__btn--frost:hover::before{transform:translateX(0)}
.hv-09__btn--frost::after{
content:'';position:absolute;top:0;right:0;width:60%;height:100%;
background:linear-gradient(270deg,rgba(59,130,246,.55),transparent);
transform:translateX(100%);
transition:transform .5s ease;
pointer-events:none;
}
.hv-09__btn--frost:hover::after{transform:translateX(0)}
/* 4 — holographic foil */
.hv-09__btn--holo{
background:conic-gradient(from 0deg,#6366f1,#8b5cf6,#ec4899,#f59e0b,#10b981,#06b6d4,#6366f1);
background-size:200% 200%;
background-position:0% 50%;
color:#fff;
transition:background-position .6s,filter .4s;
}
.hv-09__btn--holo:hover{
background-position:100% 50%;
filter:brightness(1.2) saturate(1.3);
}
/* 5 — shimmer wash */
.hv-09__btn--wash{
background:linear-gradient(135deg,var(--sky),var(--indigo));
color:#fff;
}
.hv-09__btn--wash::before{
top:0;left:-100%;width:100%;height:100%;
background:linear-gradient(
90deg,
transparent 0%,
rgba(255,255,255,.6) 50%,
transparent 100%
);
}
.hv-09__btn--wash:hover::before{
animation:hv-09-wash .9s ease-in-out forwards;
}
@keyframes hv-09-wash{
0%{left:-100%}
100%{left:100%}
}
@media(max-width:500px){.hv-09__row{flex-direction:column;align-items:flex-start}}
@media(prefers-reduced-motion:reduce){
.hv-09__btn::before,.hv-09__btn::after{transition:none!important;animation:none!important}
}How this works
The core shimmer pattern places a ::before pseudo-element with a linear-gradient(105deg, transparent 40%, rgba(255,255,255,.6) 50%, transparent 60%) on it, sized wider than the button. On hover, transform: translateX() sweeps it from left to right — at translateX(-150%) the gloss strip is fully off-screen left; at translateX(200%) it clears the right edge. The button uses overflow: hidden to clip the overrun.
The holographic variant uses a conic-gradient on the button background that shifts background-position on hover, cycling through hues to simulate iridescent foil. The spotlight uses radial-gradient(circle at var(--x,50%) var(--y,50%), ...) where --x/--y are fixed at center for the pure-CSS version — the JS-enhanced version in a later demo would move them with the cursor.
Customize
- Adjust shimmer width by changing the gradient stop positions:
40%, 50%, 60%gives a narrow streak;20%, 50%, 80%gives a broad soft sweep. - Slow the streak to
.8sfor a dreamy, luxury-product feel or speed it to.25sfor a snappy tech-tool aesthetic. - Change the gloss angle by editing
linear-gradient(105deg,...—45deggives a corner-to-corner diagonal;90dega straight horizontal wipe. - Add color to the shimmer by replacing
rgba(255,255,255,.6)with a tinted rgba value — gold shimmer:rgba(255,215,0,.5). - Trigger the shimmer on focus-visible as well as hover by duplicating the
:hover::beforeruleset as:focus-visible::beforefor keyboard accessibility.
Watch out for
- The shimmer strip must start fully off-screen — if
translateX(-100%)doesn't clear the button width entirely, use-150%or increase the pseudo-element width. - The shimmer competes with any
box-shadowglow on the button — keep glow subtle (0 4px 20px) so the moving streak remains the visual focus. - On touch devices
:hoverfires on tap but the shimmer may not complete its full sweep before the finger lifts — consider a shorter duration for mobile.
Browser support
| Chrome | Safari | Firefox | Edge |
|---|---|---|---|
| 60+ | 12+ | 60+ | 60+ |
All shimmer variants use standard gradients and transforms — no compatibility issues in modern browsers.