Friday, November 21, 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
32405 POSTS0 COMMENTS
Milvus
97 POSTS0 COMMENTS
Nango Kala
6781 POSTS0 COMMENTS
Nicole Veronica
11928 POSTS0 COMMENTS
Nokonwaba Nkukhwana
11995 POSTS0 COMMENTS
Shaida Kate Naidoo
6907 POSTS0 COMMENTS
Ted Musemwa
7165 POSTS0 COMMENTS
Thapelo Manthata
6862 POSTS0 COMMENTS
Umr Jansen
6847 POSTS0 COMMENTS