Friday, September 5, 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
32264 POSTS0 COMMENTS
Milvus
81 POSTS0 COMMENTS
Nango Kala
6634 POSTS0 COMMENTS
Nicole Veronica
11801 POSTS0 COMMENTS
Nokonwaba Nkukhwana
11863 POSTS0 COMMENTS
Shaida Kate Naidoo
6750 POSTS0 COMMENTS
Ted Musemwa
7025 POSTS0 COMMENTS
Thapelo Manthata
6701 POSTS0 COMMENTS
Umr Jansen
6718 POSTS0 COMMENTS