Saturday, October 25, 2025
HomeLanguagesJavascriptHow to create custom cursor using CSS ?

How to create custom cursor using CSS ?

A custom cursor enhances the readability of the document and grabs the user’s attention to a specific part of the webpage. Today we are going to learn how to create a custom cursor for a webpage using HTML, CSS, and Javascript.

Approach:

  • Hide the default cursor.
  • Define the classes which contain all the animations.
  • Add and remove these classes dynamically when the mouse button is pressed or when the mouse pointer is moved.

Example: This example shows the use of the above-explained approach.

HTML




<!DOCTYPE html>
<html>
  
<body>
    <div class="custom-cursor"></div>
</body>
    
</html>


CSS




:root {
    --color: 255, 71, 84;
    --cursor-size: 30px;
}
  
* {
    cursor: none;
}
  
html,
body {
    height: 100%;
}
  
body {
    margin: 0;
    overflow: hidden;
  
    background: #121212;
}
  
.custom-cursor {
    position: absolute;
    z-index: 99;
    top: 0;
    left: 0;
  
    width: var(--cursor-size);
    height: var(--cursor-size);
  
    border: calc(var(--cursor-size)
                /30) solid #fff;
    border-radius: 50%;
  
    animation: cursor 800ms infinite 
            alternate ease-in-out;
      pointer-events: none;
}
  
.custom-cursor::before {
    content: "";
    display: block;
    width: calc(var(--cursor-size) / 2);
    height: calc(var(--cursor-size) / 2);
  
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
  
    border: calc(var(--cursor-size) / 6
            solid rgba(var(--color), 0.5);
  
    border-radius: 50%;
  
    animation: cursor-before 800ms infinite 
            alternate ease-in-out;
}
  
.custom-cursor.click {
    animation: cursor-click 800ms 
        normal ease-in-out;
}
  
@keyframes cursor {
    from {
        transform: scale(1);
        border-color: #fff;
    }
  
    to {
        transform: scale(1.5);
        border-color: rgb(var(--color));
    }
}
  
@keyframes cursor-before {
    from {
        transform: translate(-50%, -50%) scale(1);
        border-color: rgba(var(--color), 0.5);
    }
  
    to {
        transform: translate(-50%, -50%) scale(1.5);
        border-color: rgba(var(--color), 0.75);
    }
}
  
@keyframes cursor-click {
  
    0%,
    100% {
        transform: scale(1);
    }
  
    50% {
        transform: scale(2.5);
        border-color: rgb(var(--color));
    }
}


Javascript




const cursor = document
    .querySelector(".custom-cursor");
  
// Adding the animations when the
// mouse button is clicked
  
window.addEventListener("mousedown", (event) => {
    if (!cursor.classList.contains("click")) {
        cursor.classList.add("click");
  
        setTimeout(() => {
            cursor.classList.remove("click");
        }, 800);
    }
});
  
// Getting the position of the cursor
window.addEventListener("mousemove", (event) => {
    let x = event.pageX - cursor.offsetWidth / 2,
        y = event.pageY - cursor.offsetHeight / 2;
  
    cursor.style.left = `${x}px`;
    cursor.style.top = `${y}px`;
});


Output: Click here to check the live Output.

RELATED ARTICLES

Most Popular

Dominic
32361 POSTS0 COMMENTS
Milvus
88 POSTS0 COMMENTS
Nango Kala
6728 POSTS0 COMMENTS
Nicole Veronica
11892 POSTS0 COMMENTS
Nokonwaba Nkukhwana
11954 POSTS0 COMMENTS
Shaida Kate Naidoo
6852 POSTS0 COMMENTS
Ted Musemwa
7113 POSTS0 COMMENTS
Thapelo Manthata
6805 POSTS0 COMMENTS
Umr Jansen
6801 POSTS0 COMMENTS