30 CSS Hover Effects 16 / 30

CSS Spotlight Card Hover Effect

Four spotlight and lighting hover effects on cards — radial gradient center spotlight, corner-origin light sweep, edge scanline, and vignette-lift — using CSS radial-gradient pseudo-elements to simulate a focused light source illuminating the card face on hover.

Pure CSS MIT licensed
Live Demo Open in tab

This is a full-page demo — interact inside the frame above, or open it in the playground for the full-screen experience.

Open in playground

The code

<div class="hv-16">
  <div class="hv-16__grid">
    <div class="hv-16__card hv-16__card--center">
      <div class="hv-16__content">
        <div class="hv-16__icon">◎</div>
        <h3 class="hv-16__title">Center Spot</h3>
        <p class="hv-16__text">Radial gradient fades in from the center on hover.</p>
      </div>
    </div>
    <div class="hv-16__card hv-16__card--corner">
      <div class="hv-16__content">
        <div class="hv-16__icon">◤</div>
        <h3 class="hv-16__title">Corner Light</h3>
        <p class="hv-16__text">Conic light sweep from the top-left corner lamp.</p>
      </div>
    </div>
    <div class="hv-16__card hv-16__card--scan">
      <div class="hv-16__content">
        <div class="hv-16__icon">▤</div>
        <h3 class="hv-16__title">Edge Scan</h3>
        <p class="hv-16__text">Bright scan band sweeps top to bottom on hover.</p>
      </div>
    </div>
    <div class="hv-16__card hv-16__card--vignette">
      <div class="hv-16__content">
        <div class="hv-16__icon">◉</div>
        <h3 class="hv-16__title">Vignette Lift</h3>
        <p class="hv-16__text">Dark vignette fades out revealing the full card face.</p>
      </div>
    </div>
  </div>
</div>
.hv-16,.hv-16 *,.hv-16 *::before,.hv-16 *::after{box-sizing:border-box;margin:0;padding:0}
.hv-16 ::selection{background:#0f766e;color:#fff}
.hv-16{
  --bg:#020c0b;
  --text:#ccfbf1;
  --dim:#6b7280;
  --teal:#14b8a6;
  --green:#10b981;
  --cyan:#06b6d4;
  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-16__grid{
  display:grid;grid-template-columns:repeat(2,1fr);gap:32px;
  max-width:720px;width:100%;
}

/* shared card */
.hv-16__card{
  position:relative;overflow:hidden;
  min-height:220px;border-radius:16px;
  background:rgba(255,255,255,.04);
  border:1px solid rgba(255,255,255,.1);
  cursor:pointer;
  transition:border-color .4s,transform .4s;
}
.hv-16__card:hover{
  border-color:rgba(20,184,166,.3);
  transform:translateY(-4px);
}
.hv-16__card::before{
  content:'';position:absolute;inset:0;
  pointer-events:none;
  transition:opacity .4s;
}
.hv-16__content{
  position:relative;z-index:1;
  padding:32px;display:flex;flex-direction:column;gap:12px;
}
.hv-16__icon{font-size:1.8rem;color:var(--teal)}
.hv-16__title{font-size:1.05rem;font-weight:700;color:var(--text)}
.hv-16__text{font-size:.85rem;color:var(--dim);line-height:1.5}

/* 1 — center spotlight */
.hv-16__card--center::before{
  background:radial-gradient(circle at 50% 50%,rgba(20,184,166,.18) 0%,transparent 65%);
  opacity:0;
}
.hv-16__card--center:hover::before{opacity:1}

/* 2 — corner sweep */
.hv-16__card--corner::before{
  background:conic-gradient(from 225deg at 0% 0%,rgba(6,182,212,.25),transparent 40%);
  opacity:0;
}
.hv-16__card--corner:hover::before{opacity:1}

/* 3 — scan band */
.hv-16__card--scan::before{
  background:linear-gradient(180deg,transparent 0%,rgba(20,184,166,.15) 40%,rgba(20,184,166,.15) 60%,transparent 100%);
  opacity:0;
  transform:translateY(-100%);
  transition:opacity .3s,transform .5s cubic-bezier(.4,0,.2,1);
}
.hv-16__card--scan:hover::before{opacity:1;transform:translateY(60%)}

/* 4 — vignette lift */
.hv-16__card--vignette::before{
  background:radial-gradient(ellipse at center,transparent 40%,rgba(0,0,0,.7) 100%);
  opacity:1;
  transition:opacity .4s;
}
.hv-16__card--vignette:hover::before{opacity:0}

@media(max-width:520px){.hv-16__grid{grid-template-columns:1fr}}
@media(prefers-reduced-motion:reduce){
  .hv-16__card,.hv-16__card::before{transition:none!important}
}

How this works

The spotlight effect uses a ::before pseudo-element with background: radial-gradient(circle at 50% 50%, rgba(255,255,255,.15) 0%, transparent 65%) and opacity: 0 at rest. On hover, opacity: 1 fades the gradient in, creating the impression of a direct light beam hitting the card from above. The mix-blend-mode: overlay on the pseudo-element blends the white circle into the card content, brightening both the background and the text simultaneously.

The corner light sweeps a conic-gradient(from 225deg at 0% 0%, rgba(255,255,255,.2), transparent 40%) from zero opacity to full, simulating a lamp positioned at the top-left corner. The vignette-lift inverts the approach: the resting state has a dark radial-gradient(ellipse at center, transparent 40%, rgba(0,0,0,.6) 100%) vignette that fades out on hover, making the card face appear to illuminate as it lifts.

Customize

  • Move the spotlight to a fixed corner by changing circle at 50% 50% to circle at 80% 20% for a top-right light source position.
  • Tint the spotlight by replacing rgba(255,255,255,.15) with a colored rgba — a warm rgba(255,200,100,.12) reads as incandescent.
  • Increase spotlight size by widening the gradient spread — circle at 50% 30% with a stop at 80% creates a floodlight rather than a focused spot.
  • Combine with a transform: translateZ(10px) on hover for a subtle 3D lift that pairs naturally with the lighting illusion.
  • Add a second pseudo-element using ::after as a softer fill light from the opposite corner for a two-point lighting setup.

Watch out for

  • mix-blend-mode: overlay on the spotlight pseudo-element requires the parent to have a non-transparent background — on transparent containers the blend has nothing to composite against.
  • The spotlight ::before must be pointer-events: none to avoid blocking clicks on interactive children like buttons inside the card.
  • Very high opacity radial gradients (.5+) can wash out dark-colored text — keep the spotlight highlight below .2 opacity and rely on the large radius for spread.

Browser support

ChromeSafariFirefoxEdge
60+ 12+ 60+ 60+

radial-gradient and mix-blend-mode are universally supported in modern browsers.

Search CodeFronts

Loading…