Create a custom cursor
Hey,
Before we start, we should all know what a custom cursor is. Creative Development enthusiasts or those who often look at sites on AWWWARDS probably have a small idea of what it is — but here's an example and what we'll build in this article.
It's a rather cool effect that you can find on certain sites. At first sight one wonders how to do it and might think it's a bit complex. I'll reassure you — it isn't. To do this we'll need three files: HTML - CSS - JS. Without further delay, let's dive into the code!
The HTML
After creating your files (index.html - style.css - app.js) all in the same folder, we'll go to the HTML file and write this:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link href="style.css" rel="stylesheet" />
<script src="app.js" defer></script>
<title>Test</title>
</head>
<body>
<div id="mouse"></div>
</body>
</html>
I think this is the easiest part — we just have a single div in our body, and that's the one that'll serve as our cursor. So on the HTML side, we're done!
The CSS
Now let's go to style.css, and the first thing we'll do is give a bit of style to our div:
#mouse {
position: absolute;
top: 50%;
left: 50%;
width: 50px;
height: 50px;
background-color: none;
border-radius: 50%;
border: 2px solid #000;
transform: translate(-50%, -50%);
}
And in the center of our screen we should have:
The
transform: translate(-50%, -50%);allows us to center the cursor relative to the div.
Those who don't understand why it's centered can check out my article on CSS Positioning where I explain this kind of behavior in more detail.
So for now nothing complicated, but as you may have noticed, the regular cursor still appears on the screen, completely independent from our div ( #mouse ), and we wonder how to make our cursor depend on our div. That's where Mr. JavaScript comes in.
The JavaScript
Going into app.js, the first thing we'll do is select our div:
const mouse = document.querySelector('#mouse')
Now thanks to addEventListener we'll be able to attach an event listener to our div. In our case we'll use mousemove (basically it triggers each time the cursor moves). So in our code we should have something like this:
const mouse = document.querySelector('#mouse')
mouse.addEventListener('mousemove', (e) => {})
The goal right now is to be able to
change the position of our div each time we move the cursor. The position values we should assign to the divmust be the same as those of the cursor at that instant— this will make the div and cursor be in the same place at the same time.
And we say: "OK LN, it's all great but how do we do this?" Well... JavaScript has properties to detect the position value (in pixels (px)) on the X and Y axes of the cursor. So we have: pageX and pageY
The goal will be to assign these values to top: ; and left: ; of our div, which is child's play:
const mouse = document.querySelector("#mouse");
mouse.addEventListener("mousemove", (e) => {
mouse.style.top = e.pageY + "px";
mouse.style.left = e.pageX + "px";
});
I don't know if you noticed but the result is a bit "weird" — look:
We notice that
the cursor and div aren't really in sync, which meansthe div only moves when the cursor is on it, but if we try to QUICKLY move the cursor, they're no longer together.
Try to guess where the problem is :) ... It's here:
When we did
addEventListenerwe attached it to the div (mouse.addEventListener), and that's the reason — with this, the position of the div changes only when the mouse is on it.
You're then wondering how to fix this. It's very easy: instead of attaching to the div, we'll attach to the window element, which gives us:
const mouse = document.querySelector('#mouse')
window.addEventListener('mousemove', (e) => {
mouse.style.top = e.pageY + 'px'
mouse.style.left = e.pageX + 'px'
})
And the result is flawless :)
The div always follows the cursor wherever it goes! Now it's also possible to remove the default cursor and only leave the div (like in the demo at the intro), and this is done in CSS — we just need to add this at the start of our code:
html {
cursor: none;
}
And we have this:
We've reached the end of this article and I hope you liked it. If so, feel free to share it on your networks and also ask your questions if you didn't quite understand a point. So see you in the next article, ciao! It was LN 👋
- Previous article: Flexbox part 1
- Next article: Flexbox part 2
If you have feedback or questions,
feel free to reach out on Twitter (X) or by email.