How to change the mouse cursor to any CSS shape in Javascript

Blog Problem Solving Tutorial

This tutorial shows how to change a normal HTML cursor to any CSS shape and change the cursor on certain HTML elements such as hyperlinks, buttons, inputs, and certain CSS classes.

This tutorial will show you how to change your website cursor to any CSS shape and change the shape on hover on certain HTML elements.

I have seen a lot of tutorials online about changing the HTML cursor to an SVG icon or to a PGN icon. In my case, I would like to change the cursor to any CSS shape or to any CSS form. In this tutorial, I will use a simple semi-transparent circle as a cursor.

The idea is very simple, I will hide the normal HTML cursor from the whole website in CSS using the attribute “cursor: none;”, then with Javascript I will detect the position of the cursor at any movement of it and I will change the position of the CSS shape (a circle in my case) based on the current cursor position. In other words, I will swap the cursor with the CSS shape anytime the cursor moves.

This sounds very simple so far, but because I want to make my life harder, I also want to change the dimension and the color of the CSS circle anytime the cursor hovers over certain elements, let’s say that I want to change the shape anytime the cursor hove clickable HTML elements, such as hyperlinks, button, input, and a certain element with CSS class ‘.js-big-cursor’.

To do that I just need to check with Javascript if the cursor is on top of the mentioned HTML element, and I will add to the CSS circle the CSS class ‘.enlarged’, this will change the circle shape as I want.

Here is the CSS involved in this tutorial:

// remove cursor from the whole body
body {
    cursor: none;
}

// remove cursor from HTML clickable elements
a,
button,
input {
    cursor: none;
}

// this is the CSS circle
#circle-cursor {
    position: fixed;
    z-index: 100;
    width: 64px;
    height: 64px;
    background-color: rgba(#fff, 0.75);
    border-radius: 50%;
    pointer-events: none;
    transition: transform ease 0.34s, background-color ease 0.34s, mix-blend-mode ease 0.34s;
    transform: scale(0.5) translate3d(0, 0, 0); 
    -webkit-transform: scale(0.5) translate3d(0, 0, 0);
    mix-blend-mode: difference;
}

// make the circle bigger and change color
.enlarged {
    transform: scale(1) translate3d(0, 0, 0);
    -webkit-transform: scale(1) translate3d(0, 0, 0);
    background-color: rgba($brand-primary, 0.75);
    mix-blend-mode: initial;
}

Here is the JS involved, please note that you don’t need to wrap this code in jQuery function, the following JS code is not jQuery:

jQuery(function ($) {

    // this is the CSS circle
    const circle = document.getElementById('circle-cursor');

    // these are the clickable elements
    const links = document.querySelectorAll('a,button,input,.js-big-cursor');
    const circleStyle = circle.style;

    // add or remove CSS class 'enlarged'
    links.forEach(link => {
        link.addEventListener('mouseenter', e => {
            circle.classList.add('enlarged')
        })
        link.addEventListener('mouseout', e => {
            circle.classList.remove('enlarged')
        })
    })

    // change position of the circle based on mouse position
    document.addEventListener('mousemove', e => {
        window.requestAnimationFrame(() => {
            circleStyle.top = `${e.clientY - circle.offsetHeight / 2}px`;
            circleStyle.left = `${e.clientX - circle.offsetWidth / 2}px`;
        });
    });
});

… and the only thing left is adding the HTML tag for the CSS shape to your HTML page, I suggest adding this HTML tag just under the <body>:

<div id="circle-cursor"></div>

As usual, I have created a Codepen sample for this tutorial, so you can play around with it and see how the CSS circle changes when you hover over the other elements, here is the link:
https://codepen.io/webmarcello8080/pen/OJZqBLV

Click to Leave a Comment

You May Like

How to animate HTML elements and slide them in on mouse scroll using CSS and Javascript Today I want to animate a bunch of HTML elements and create an animation that moves them inside the same parent DIV once the elements are in the viewport, so only when the elements are visible to the users. […]

August 29, 2023
Read More...
woocommerce-min-max-checkout-plugin

Woocommerce Min Max Checkout is a plugin that extends your Woocommerce e-commerce in order to give you the possibility to set the minimum or maximum checkout amount or in order to set a minimum or maximum order quantity on the cart or checkout pages. With Woocommerce Min Max Checkout you can also set e customizable […]

February 12, 2022
Read More...

How to add Read More/Read Less button next to a too long HTML element. This tutorial will take you through how to display a certain number of rows of an HTML element and hide the rest of it, then we will see how to read a clickable “Read More” element at the end of the […]

January 15, 2022
Read More...