Card Spotlight

A highlight that tracks the pointer across a card surface.

← All motions

Card Spotlight

Two soft lights follow the cursor: a wash on the card surface and a glow along the border. The surface one is easy. The border one is the detail that separates a polished component from a first-attempt grid — and it needs a mask, not an overflow: hidden.

trigger: cursor CSS custom properties mask-composite

Live demo

01

Analytics

Move the pointer across this card. The light follows on both the surface and the edge.

02

Automations

Each card keeps its own position state — nothing is shared between siblings.

03

Reporting

The effect costs two style writes per frame and no layout reads.

The prompt

Add a pointer-tracked spotlight to a grid of cards — a soft wash across the surface plus a glow along the border.

Surface highlight:
- On pointermove, compute the pointer position relative to the card's bounding box and write it into two CSS custom properties on that card: --mx and --my, in pixels.
- Render the wash with a ::before pseudo-element covering the card: radial-gradient(200px circle at var(--mx) var(--my), rgba(120,160,255,.16), transparent 65%).
- Fade it in with opacity on :hover, not by toggling display — display changes cause layout work.

Border glow:
- Use a ::after pseudo-element with inset: 0, border-radius: inherit and padding: 1px.
- Give it the same radial gradient but brighter, then punch out the middle with a mask:
  -webkit-mask: linear-gradient(#000,#000) content-box, linear-gradient(#000,#000);
  -webkit-mask-composite: xor;
  mask-composite: exclude;
- Do not try to do this with overflow: hidden — that clips the glow to the inside edge and it disappears.

Constraints:
- Cache the bounding rect on pointerenter; never call getBoundingClientRect() inside pointermove.
- Write only custom properties. Never set left/top on the highlight element.
- Skip the whole effect under @media (hover: none) so touch devices are unaffected.
- Respect prefers-reduced-motion: keep the static hover state, remove the transition timing.
- Keep a visible :focus-visible outline — the spotlight is decorative and must never be the only indication of focus.

What actually makes it work

Compatibility and performance

AspectDetail
CSS custom propertiesUniversal.
mask-compositeChrome 120+, Safari 15.4+, Firefox 53+ via the standard property. In older Safari only the -webkit- form applies — ship both.
DegradationIf masking is unsupported the border glow is simply absent; the surface wash still works and the card is unchanged.

The one thing to watch is the number of cards. Twenty spotlit cards on one page means twenty pseudo-element pairs repainting as the pointer moves. That is still cheap, but on a low-end device it is the first thing to drop — in which case keep the effect on the hovered card only and remove it from the rest.

When not to use it

Don't use it to imply interactivity a card doesn't have. A light that follows the cursor reads as "this is clickable". If the card is not a link, add no cursor change and no hover lift — or better, remove the effect.

Don't stack it with a tilt and a glow and a scale. Three simultaneous pointer reactions on one card is the most common way this effect goes from premium to gimmicky.

Don't ship it without a keyboard story. Pointer-only feedback means keyboard users see nothing. Pair it with a clear :focus-visible outline of equal prominence.