Custom cursor doesn't move with page when scroll

Issue

I have built a custom cursor, but im having an issue with its position when you scroll the page. Rather than following the mouse cursor, it stays where it was on the page until you move the mouse again and then it catches up.

let mouseCursor = document.querySelector(".cursor");

window.addEventListener('DOMContentLoaded', cursor);
window.addEventListener('mousemove', cursor);
document.addEventListener('mouseenter', () => mouseCursor.style.display = 'block');
document.addEventListener('mouseleave', () => mouseCursor.style.display = 'none');


if (/Android|webOS|iPhone|iPad|iPod|BlackBerry|Windows Phone/i.test(navigator.userAgent)) {
      jQuery('.cursor').remove();
    } else {
      mouseCursor.style.display = 'block';
    }

function cursor(e){

    mouseCursor.style.top = "calc(" +e.pageY + "px - 1rem)";
    mouseCursor.style.left = "calc(" +e.pageX + "px - 1rem)";
}
.section{
height:200vh;
}


.cursor{
    display:none;
    width: 20px;
    height: 20px;
    border: 2px solid #f2f2f2;
    outline: 2px solid #000;
    border-radius: 50%;
    position: absolute;
    transition: all 0.3s ease;
    transition-property: background, transform;
    transform-origin: center center;
    z-index: 20000;
    pointer-events: none;
}
<div class="cursor"></div>

<div class="section"></div>

Solution

You need to work with clientX/Y property not pageX/Y.
Because clientX/Y coordinates are relative to the top left corner of the visible part of the page, while pageX/Y is relative to the top left corner of the whole page.

Also, Instead of making your circle position:absolute , you have to change it to position:fixed;

Elements with fixed positioning are fixed with respect to the viewport

CSS absolute and fixed positioning

let mouseCursor = document.querySelector(".cursor");

window.addEventListener('DOMContentLoaded', cursor);
window.addEventListener('mousemove', cursor);
document.addEventListener('mouseenter', () => mouseCursor.style.display = 'block');
document.addEventListener('mouseleave', () => mouseCursor.style.display = 'none');


if (/Android|webOS|iPhone|iPad|iPod|BlackBerry|Windows Phone/i.test(navigator.userAgent)) {
      jQuery('.cursor').remove();
    } else {
      mouseCursor.style.display = 'block';
    }

function cursor(e){

    mouseCursor.style.top = "calc(" +e.clientY + "px - 1rem)";
    mouseCursor.style.left = "calc(" +e.clientX + "px - 1rem)";
}
.section{
height:200vh;
}


.cursor{
    display:none;
    width: 20px;
    height: 20px;
    border: 2px solid #f2f2f2;
    outline: 2px solid #000;
    border-radius: 50%;
    position: fixed;
    transition: all 0.3s ease;
    transition-property: background, transform;
    transform-origin: center center;
    z-index: 20000;
    pointer-events: none;
}
<div class="cursor"></div>

<div class="section"></div>

Answered By – Ido Bouskila

This Answer collected from stackoverflow, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply

(*) Required, Your email will not be published