Mouse cursor gradient tracking
Cursor tracking effects are cool, but they're generally tricky to implement. Luckily, CSS custom properties make implementation much easier, especially when combined with some simple JavaScript for DOM manipulation.
HTML structure
For this example, we'll use a <button>
element with a <span>
child. The <span>
will contain the text that will be hovered over. The <span>
is necessary, as we will be applying the gradient to the button's ::before
pseudo-element. Without the <span>
, the gradient would be applied on top of the button's text, making it hard to read.
<button class="mouse-cursor-gradient-tracking"> <span>Hover me</span> </button>
The gradient's CSS
As mentioned previously, we'll use the ::before
pseudo-element to create the gradient. For this to work, we'll have to use position: absolute
on the pseudo-element, which means the <button>
itself needs to have position: relative
.
We'll also need to declare two CSS variables, --x
and --y
, to track the position of the mouse on the button. We'll make sure to update these with JavaScript a little bit later.
Finally, we'll use a third CSS variable, --size
, to modify the gradient's dimensions. This variable, will start at 0
, and will be updated to 200px
when the button is hovered over.
.mouse-cursor-gradient-tracking { position: relative; background: #7983ff; overflow: hidden; } .mouse-cursor-gradient-tracking span { position: relative; pointer-events: none; } .mouse-cursor-gradient-tracking::before { --size: 0; content: ''; position: absolute; left: var(--x); top: var(--y); width: var(--size); height: var(--size); background: radial-gradient(circle closest-side, pink, transparent); transform: translate(-50%, -50%); transition: width 0.2s ease, height 0.2s ease; } .mouse-cursor-gradient-tracking:hover::before { --size: 200px; }
Tracking the mouse with JavaScript
Tracking the mouse is relatively simple. We'll first use Document.querySelector()
to select the button, and then use EventTarget.addEventListener()
to register a handler for the 'mousemove'
event.
Every time the listener is triggered, we'll use Element.getBoundingClientRect()
to get the button's position on the screen, and then use CSSStyleDeclaration.setProperty()
to update the values of the --x
and --y
CSS variables.
When these two values change, the gradient will update its position, making it look like it's following the mouse cursor.
const btn = document.querySelector('.mouse-cursor-gradient-tracking'); btn.addEventListener('mousemove', e => { const rect = e.target.getBoundingClientRect(); const x = e.clientX - rect.left; const y = e.clientY - rect.top; btn.style.setProperty('--x', x + 'px'); btn.style.setProperty('--y', y + 'px'); });
Putting everything together gives us a nice hover effect where the gradient follows the mouse cursor. You can see the final result in the CodePen below: