Creating a custom cursor using CSS?
Tags: javascript, css, webdev
Published: 2020-09-11 12:47:51

Cascading Style Sheet (CSS) offers you the opportunity to create pretty awesome designs. from SVGs to animation to the box model concept, CSS let's you go wild with your imagination acting has the only barrier.

One of such awesome designs is creating your custom cursor.
There are over 30 different kinds of cursor, from *pointer* to *help*. this [codepen](https://codepen.io/benlinton/pen/JXzZBp) shows you the different kind of cursor available.

Creating a custom cursor is fairly simple, I will show you the easy way which uses an SVG then we will move from there.

## CREATING A CUSTOM CURSOR USING AN SVG IMAGE

1. Create a simply html page with just the body tag.
2. Create your style sheet and just give the body tag a background color of red.
3. Get a cool SVG that you want to use and just link it to your CSS. Note that for this to work you also have to pass a second value of auto. This will be the default cursor in case the image is not available.
```
body {
background:red;
cursor:url('cursor.svg'),auto;
}
```
Try it out. It worked I hope.

Now that is awesome. But we want to go further than that. We wanna add cool animation, such that when you click, it does this and that etc.
It might actually be possible to do that with the svg, but that might get out of hand. So we will create another type of cursor.

## CREATING A CUSTOM CURSOR USING ELEMENTS

Now let's first get rid of everything we have done earlier

1. Then create a simple div with a class of cursor.
2. Style the div. You can style this div anyhow, make it a triangle, square etc. I am going with a circle and also, give the body a couple other styles
```
body {
margin: 0;
padding: 0;
height: 100vh;
background:black;
} 
.cursor {
width:20px
height:20px
border:2px solid white;
border-radius:50%;
}
```
3. So moving on, the next thing to do is give our div a position that is relative to the body tag. **position:absolute;** will work just fine. I will not go in-depth about positioning, just know that this will place the div at the top left corner of the parent tag in this case that is the body tag
```
.cursor {
//other styles
position:absolute;
}
```
Now to make it a functional cursor we will add a few scripts
4. Create a script file and link it to your html, get the cursor tag and add an eventListener of mousemove to the whole body
```
let cursor =document.querySelector(".cursor")
document.addEventListener("mousemove",function(e){
console.log(e)
})
```
5. `mousemove` basically gives you the position of your mouse has you hover the screen. it returns an object which contains a lot of properties. But what we need is the pageX and pageY. This two values is basically the position of the cursor from the left and top of your browser window respectively and this is what we are going to use to change the position of the div element
```
// MouseEvent {isTrusted: true, screenX: 470, screenY: 219, clientX: 470, clientY: 148, …}
document.addEventListener("mousemove",function(e){
cursor.setAttribute("style",
`top: ${e.pageY}px;left:${e.pageX}px`
)
})
```
6. Now, you should have a cursor that moves with your default cursor. Nice. Note that you could totally do this a different way,you can change the values respectively using JS with **cursor.style.left** and **cursor.style.top**. That also works.
Like the popular saying there is about a thousand ways to do one thing.
7. But there is a slight issue, the div is actually not at the exact point the cursor is, there is kind of a small difference. This is the same thing that happens when you try to position an element to the center of a page with position absolute. It is always slightly off and that is because it takes the whole element to the center which is not suppose to be so. Half of the element has to be on one side and the other half on the other side. So in this case, all you need to do is every time you position it with pageX and PageY, subtract exactly half of the width and height of that element from this two values i.e
```
document.addEventListener("mousemove",function(e){
cursor.setAttribute("style",
`top: ${e.pageY-10}px;left:${e.pageX-10}px`
)
})
```
One other problem with custom cursor is the fact that you cannot click on anything. You can actually, it just won't work. Button, anchor tags etc :( . But thankfully there is a solution. In your cursor class just add this.
```
pointer-events:none;
```
And you are good to go. To make it more awesome, you can go ahead and remove the custom cursor with
```
cursor:none;
```
in your body tag.

Now, you can totally stop here, that is cool. But I want to add some cool animation to this. So let do that next

So let add an effect for every time we click. So every time I click something in the document, it should expand and disappear for about .5s.
So to do this, we will work with CSS first. A class 'expand' with an animation
```
.expand {
animation: cursorAnim 0.5s forwards;
border: 1px solid red;
}
@keyframes cursorAnim {
0% {transform: scale(1) }
50% { transform: scale(3) }
100% { transform: scale(1); opacity: 0 }
}
```
So this is basically straight forward, expand has an animation property, at 50% it scales to 3x it value and at 100%, it disappears.
Now we need JavaScript to add this class to the cursor i.e every time you click the document or anywhere, add the `expand` class and after .5s remove it
```
document.addEventListener("click", function () {
cursor.classList.add("expand");
setTimeout(() => {
cursor.classList.remove("expand");
}, 500);
});
```


And that is how you create your custom mouse.
I hope you enjoyed reading it.

In this article, I talked about:
1. How to create your custom cursor using an image,(don't forget to add a second value of auto)
2. How to create your custom cursor using a div element (don't forget position:absolute and pointer-events:none)
3. And how to add animation to your custom div cursor.