Hover✨ Premium

Spotlight Effect

A 150 px radial-gradient follows the mouse in real time via CSS custom properties --spotlight-x/y updated by mousemove — the cursor illuminates the element like a lamp. JavaScript required, 400 bytes.

JSMouseLight

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

Full-width hero zone — fintech landing page — Spotlight Effect example 1

① Full-width hero zone — fintech landing page

WhenThe entire hero (540 px wide) is the spotlight's listening zone; the light spot follows the cursor across the whole dark background to create an atmosphere of exploration.
WhyA full-frame spotlight behind the hero text creates a directional atmosphere that subtly guides the eye toward the content, without covering the text.
SettingsFull-frame listening zone, spot 260×260 px, indigo radial-gradient at 40%, near-black background, hero text layered on top via z-index.
Project card grid — agency portfolio — Spotlight Effect example 2

② Project card grid — agency portfolio

WhenThree project cards side by side; on each card the spot follows the cursor independently to reveal project details (category, title, year).
WhyMultiple independent spotlight zones let the user sweep each card like a lamp, creating a personalised exploration interaction.
SettingsThree independent data-spotlight instances, spot 180×180 px per card, border-radius 12 px, indigo radial-gradient.
Product visual — online showcase of a design studio — Spotlight Effect example 3

③ Product visual — online showcase of a design studio

WhenThe product image (200×200 px) is the spotlight's listening zone; the spot simulates a gallery lamp the user moves over the product to see its details.
WhyA white spotlight on a product against a dark background evokes showroom or museum lighting, showcasing the object without a distracting animation.
SettingsProduct zone 200×200 px, spot 200×200 px, white radial-gradient at 18%, dark background, product content in z-index 1 on top.

How it works

The .fx-0357-root root centers a .hover-box.hover-spotlight block of 200 × 200 px. A 150 × 150 px ::before pseudo-element carries a radial-gradient(circle, rgba(99,102,241,.4) 0, transparent 70%); it is positioned via left: var(--spotlight-x, 50%); top: var(--spotlight-y, 50%) with transform: translate(-50%, -50%) to center the light spot on the variable's position. At rest, opacity: 0; on hover, opacity: 1.

The script searches all [data-spotlight] inside .fx-0357-root and listens to mousemove on each. On each move, it computes the cursor position within the element (clientX − rect.left) and updates --spotlight-x and --spotlight-y on the element. CSS reads these variables and repositions the ::before in real time. Under prefers-reduced-motion: reduce, the script does not register and no mouse tracking occurs.

Measured in Chromium 151: spotlight follows the mouse, two copies on a page — each spotlight tracks its own mouse independently. The effect requires a mouse: no keyboard or touch tracking.

Accessibility

  • Reduced motion: under prefers-reduced-motion: reduce, the script does not initialize and the spotlight does not follow the mouse. The element stays visible and usable without animation.
  • Keyboard and touch: the spotlight follows the mouse (mousemove) and cannot be reproduced with the keyboard or touch — an inherent limitation of pointer interaction. The element stays functional without the effect.
  • Content: the spotlight is purely decorative (pseudo-element). All text content stays accessible and readable in every state.
  • Focus: to signal keyboard focus, add :focus-visible { outline: 2px solid #6366f1; } on .hover-spotlight in your page CSS.

Browser compatibility

CSS custom properties (--spotlight-x, --spotlight-y) + 400 bytes of JavaScript (mousemove, getBoundingClientRect, matchMedia), no dependencies. Measured in Chromium 151: precise mouse tracking, two independent copies. CSS custom properties available since Chrome 49, Firefox 31, Safari 9.1.

Chrome 49+✓ Full (measured)
Firefox 31+✓ Full
Safari 9.1+✓ Full
Edge 79+✓ Full (Chromium engine)
Mobile iOS✓ Not applicable (no mouse, effect does not trigger)
Android Chrome 49+✓ Not applicable (no mouse, effect does not trigger)

Without JavaScript, the spotlight does not activate and the element stays at rest. Without CSS custom properties, the pseudo-element stays centered (default value 50%).

The code

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

index.html — structure
<div class="fx-0357-root">
  <div class="hover-box hover-spotlight" data-spotlight="">
    <span>…</span>
  </div>
</div>

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

Customize

Options passed to the API or data-* attributes:

Option / propertyDefaultEffect
Spotlight radius (CSS — width / height of ::before) 150 × 150 px A larger radius (200 px) gives a more diffuse light; smaller (80 px) concentrates the beam.
Light color (CSS — rgba(99,102,241,.4) in the radial-gradient) Indigo at 40% opacity Change color and opacity: rgba(255,255,255,.3) for white light; rgba(251,191,36,.5) for amber vintage spotlight light.
Gradient softness (CSS — 0, transparent 70%) Full center, fade from 0 to 70% transparent 50% gives a harder light circle; transparent 90% spreads light over almost the entire element.
Opacity at rest (CSS — opacity: 0 on ::before) Invisible at rest opacity: .1 leaves a faint permanent glow, indicating the spotlight is active even without hovering.
Listening zone (HTML — data-spotlight) The .hover-spotlight element itself Put data-spotlight on a larger container to extend the tracking zone without changing the size of the illuminated element.

FAQ

No: the spotlight follows mousemove which is not triggered by an ordinary touch. On mobile, the element stays at rest. The effect is designed for cursor interfaces.
The script targets all [data-spotlight] inside each .fx-0357-root and gives each its own independent listener. Duplicate the HTML structure as many times as needed — each spotlight tracks its own mouse.
No: overflow: hidden on .hover-box keeps the ::before inside the element. Remove overflow: hidden if you want the glow to slightly overflow.