DEV Community

Cover image for Spotlight effect with JS and CSS
David Lange for Finiam

Posted on • Edited on • Originally published at blog.finiam.com

8 2 1

Spotlight effect with JS and CSS

Spotlight effects can be a pretty creative way of revealing content on your website. And they're surprisingly easy to create with a little JS and CSS!

The basic idea

TLDR; Use CSS radial gradient backgrounds, and then use JS to track the mouse movement and move the center of the gradient.

There are other, more complex ways of doing this - you could use canvas or external libraries - but I find the simpler approach is a good starting point and should work well enough for most use cases.

Let's get started:

#spotlight {
  position: fixed;
  opacity: 1;
  width: 100vw;
  height: 100vh;
  top: 0;
  left: 0;
  pointer-events: none;
}
Enter fullscreen mode Exit fullscreen mode
<div id="spotlight"></div>
Enter fullscreen mode Exit fullscreen mode
const spotlightEl = document.querySelector("#spotlight");

function handleMouseMove(event) {
    const { clientX, clientY } = event;

    spotlightEl.style.background = `radial-gradient(circle at ${clientX}px ${clientY}px, #00000000 10px, #000000ee 350px)`;
}

document.addEventListener("mousemove", handleMouseMove)
Enter fullscreen mode Exit fullscreen mode

And...that's pretty much it.

The #spotlight div is positioned so that it always covers the entire viewport. We then attach an event listener to listen to the mouse's movement, and set the X and Y directly in the radial-gradient CSS value.

The #00000000 10px, #000000ee 350px part basically means we want a gradient that is transparent at it's center, and at 350px from the center is a slightly transparent black. That's how the gradient center reveals what's beneath.

Making it configurable

So far we have a basic spotlight, so let's go ahead and improve it.

We can create a Spotlight class that allows you to easily set up new spotlights and pass in some options:

  • toggleEl is the id of the element you want to use as a trigger to toggle the spotlight.
  • innerRadius and outerRadius set the spotlight size.
  • outerColor sets the background color (try passing in red for a truly bleeding edge experience).

The class also provides methods for switching the spolight on and off.

Making the light feel more natural

To make it a look a little more natural, there are a couple of added touches.

First, there is a slight delay in the spotlight movement. This adds a sense of weight to the light, like we're dragging it around with our mouse.

handleMouseMove(event: MouseEvent) {
    setTimeout(() => {
      this.updateEl(event.clientX, event.clientY);
    }, 50);
}
Enter fullscreen mode Exit fullscreen mode

Also, you'll notice the light "pulses" slightly - continually increasing and decreasing.

But how do we get it to work?

My first instinct was to animate the gradient size, but that's not actually possible in CSS! Next I thought of somehow changing the outerRadius value in steps inside a function called in a setInterval, but that turned out to be a really stupid idea. Finally, I came up with the simple solution - animate the scale of the entire spotlight div with a CSS animation.

@keyframes pulse {
  0% {
    transform: scale(1);
  }
  100% {
    transform: scale(1.1);
  }
}
Enter fullscreen mode Exit fullscreen mode
this.el.style.animation =
        "pulse 3s ease-in-out infinite alternate forwards";
Enter fullscreen mode Exit fullscreen mode

This way, we don't need to touch the actual gradient, we just animate the entire "canvas", stretching the gradient in the process. I also used CSS animations for the "switching on/off" part.

Wrapping up

Obviously, you shouldn't be using spotlights in every single page (please don't!). But when used right, they're a nice way for users to feel like they're discovering some cool concealed content for the first time.

Thanks for reading!

Sentry image

See why 4M developers consider Sentry, “not bad.”

Fixing code doesn’t have to be the worst part of your day. Learn how Sentry can help.

Learn more

Top comments (0)

Sentry image

See why 4M developers consider Sentry, “not bad.”

Fixing code doesn’t have to be the worst part of your day. Learn how Sentry can help.

Learn more

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay