Sunday, January 18, 2026
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
32474 POSTS0 COMMENTS
Milvus
118 POSTS0 COMMENTS
Nango Kala
6846 POSTS0 COMMENTS
Nicole Veronica
11977 POSTS0 COMMENTS
Nokonwaba Nkukhwana
12063 POSTS0 COMMENTS
Shaida Kate Naidoo
6985 POSTS0 COMMENTS
Ted Musemwa
7219 POSTS0 COMMENTS
Thapelo Manthata
6933 POSTS0 COMMENTS
Umr Jansen
6911 POSTS0 COMMENTS