Custom Cursor with CSS and jQuery [Detailed]
Tags: css, javascript, tutorial, webdev
Published: 2020-01-21 16:49:54

Hey everyone! 2 days ago i posted [`I Built My Personal Website`](https://dev.to/b4two/i-built-my-personal-website-4mpf) and one of the questions was _What library did you use for the mouse pointer effect?_. The answer is i used no library. I did it all by myself and today i am going to show you how i did it.

First things first, we have to create our custom cursor style.

##Cursor Style
```css
 .cursor{
   position: fixed;
   width: 20px;
   height: 20px;
   border-radius: 50%;
   background-color: #f5f5f5;
   pointer-events: none;
   mix-blend-mode: difference;
   z-index: 999;

   transition: transform 0.2s;
 }
```
**Why do we use?**
```css
position: fixed;
```
It is because when we start to scroll we don't want our custom cursor to stay where we start to scroll. If you use `position: absolute` instead of fixed, cursor won't be moving as you scroll down or up the page. To prevent that you have to give the `fixed` value to `position`.

**Why do we use?**
```css
pointer-events: none;
```
Your cursor is right on top of the custom cursor you created. And whenever you want to click a link or see a hover statement this custom cursor will prevent that to be happen. If you give the `none` value to `pointer-events` you will be able to click anything you want.

**What is...**
```css
mix-blend-mode: difference;
```
The `mix-blend-mode` property defines how an element’s content should blend with its background.

`difference`: this subtracts the darker of the two colors from the lightest color.

And so this allows you to see the content behind your cursor easily.

<hr>

##jQuery DOM Manipulation
It is time to use some jQuery to make our
```html
<div class="cursor"></div>
```
element follow the default cursor.
```javascript
$(document).ready(function(){
 var cursor = $('.cursor');
});
```
Instead of writing `$('.cursor')` everytime and to make our job easier we stored it in a variable named cursor. Now let's make it follow as we move the mouse.
```javascript
$(document).ready(function(){
 var cursor = $('.cursor');

 $(window).mousemove(function(e) {
        cursor.css({
            top: e.clientY - cursor.height() / 2,
            left: e.clientX - cursor.width() / 2
        });
    });
});
```
We selected our window object and when we move our mouse in it we want our cursor's top and left positions to change. To make it happen we manipulate its css from here.

**What is...**
```javascript
top: e.clientY
left: e.clientX
```
`clientY` and `clientX` are relative to the upper left edge of the content area (the viewport) of the browser window. This point does not move even if the user moves a scrollbar from within the browser.

`pageY` and `pageX` are relative to the top left of the fully rendered content area in the browser. This reference point is below the URL bar and back button in the upper left.

And by using `clientY` instead of `pageY` we maintain our custom cursor to stay at the same position.

As you can see, to keep our custom cursor in the right position we have to give both
```css
position: fixed;
```
(in css)
and
```javascript
top: e.clientY
left: e.clientX
```
(in jQuery)
properties.

**Why do we add...**

```javascript
top: e.clientY - cursor.height() / 2
left: e.clientX - cursor.width() / 2
```
Because we want the cursor we created to be perfectly centered to our default one. As you can see above we gave `height: 20px` and `width: 20px` to our cursor.
To get the right point and center it we give
```javascript
- cursor.height() / 2
- cursor.width() / 2
```
If you didn't get it, to center absolute positioned elements we give
```css
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
```
This `transform: translate(-50%, -50%)` perfectly centers the element by taking off half of its height and width. This example is similar to what we did on jQuery. `-cursor.height()/2` and `-cursor.width()/2` are doing the same thing.

**What is going to happen when we leave our mouse from browser screen?**
```javascript
$(window)
        .mouseleave(function() {
            cursor.css({
                opacity: "0"
            });
        })
        .mouseenter(function() {
            cursor.css({
                opacity: "1"
            });
        });
```
We don't want our custom cursor to be visible at the position where we left the screen.

With this code
```javascript
$(window).mouseleave(function(){
cursor.css({opacity: "0"});
});
```
whenever we leave the screen our custom cursor's `opacity` will be `0` and can't be seen.

And with this one
```javascript
$(window).mouseenter(function(){
cursor.css({opacity: "1"});
});
```
whenever our mouse is on the screen the custom cursor's `opacity` will be `1` and can be seen.

**How do you understand if you click or not?**
```javascript
$(window)
        .mousedown(function() {
            cursor.css({
                transform: "scale(.2)"
            });
        })
        .mouseup(function() {
            cursor.css({
                transform: "scale(1)"
            });
        });
```
With these lines of code when we click (which is `mousedown`) our cursor `scales` down to `0.2` and when we don't (which is `mouseup`) it comes to its normal statement and `scales` back to `1`.

**Managing the hover statements**
```javascript
$(".link")
        .mouseenter(function() {
            cursor.css({
                transform: "scale(3.2)"
            });
        })
        .mouseleave(function() {
            cursor.css({
                transform: "scale(1)"
            });
        });
```
As you can see we have a class named `link`. If you have elements which have some effects on hover or you want your clickable items to be seen by user and want your custom cursor to change whenever you hover these elements, you can give every element that have this effect a class named link and so you can manipulate it from jQuery.

If your mouse is on the element(which is `mouseenter`) which has a link class, your cursor `scales` up to `3.2` and if you leave the hover state (which is `mouseleave`) it `scales` back to its normal state which is `1`. You can give any class name you want and manipulate your custom cursor as you wish. This is just an example, you don't have to do the same.

##Final

Don't forget these lines

```css
html,
*{
cursor: none;
}
```
to make the default cursor unseen.

At last we have our custom cursor created and functioning as we desire.

Don't forget to place your cursor element right on top of the closing `body` tag.
```html
<body>

<!--Some other elements  -->

<div class="cursor"></div>
</body>
```
Whole jQuery Code
```javascript
$(document).ready(function(){
var cursor = $(".cursor");

    $(window).mousemove(function(e) {
        cursor.css({
            top: e.clientY - cursor.height() / 2,
            left: e.clientX - cursor.width() / 2
        });
    });

    $(window)
        .mouseleave(function() {
            cursor.css({
                opacity: "0"
            });
        })
        .mouseenter(function() {
            cursor.css({
                opacity: "1"
            });
        });

    $(".link")
        .mouseenter(function() {
            cursor.css({
                transform: "scale(3.2)"
            });
        })
        .mouseleave(function() {
            cursor.css({
                transform: "scale(1)"
            });
        });

    $(window)
        .mousedown(function() {
            cursor.css({
                transform: "scale(.2)"
            });
        })
        .mouseup(function() {
            cursor.css({
                transform: "scale(1)"
            });
        });
});
```

**An example for you to see how it works**

(To get the true experience please go to codepen)

{% codepen https://codepen.io/batuhangulgor/pen/dyPwGyY %}

Also you can use [`TweenMax`](https://greensock.com/tweenmax/) for custom cursor animations. I didn't use it before but you can give it a shot if you want.

_Thanks for your time. Have a good day <3_