Creating a Custom Cursor using CSS

Temani Afif

Written by Web Developer

January 24, 2023
Creating a Custom Cursor using CSS

In this article, we will cover different ways of creating a custom cursor using only CSS. We will study two different methods. The classic one that you probably know and an advanced one lesser know. The main focus will be on the advanced method that allows us to customize a cursor using CSS without any external resources.

The Classic Method


I think it’s not a surprise if I tell you we are going to use the cursor CSS property. From the MDN page, we can read:

The cursor CSS property sets the mouse cursor, if any, to show when the mouse pointer is over an element.

and

The cursor property is specified as zero or more <url> values, separated by commas, followed by a single mandatory keyword value.

In order to update the cursor, you either consider one of the predefined keywords or use an external image.

html {
  cursor: pointer;
  cursor: help;
  cursor: progress;

  cursor: url("pointer.png"), auto
}

That’s it! All you have to do is to use your favorite image editor to create your own cursor or check the MDN page for all the predefined keywords.

This is the classic method and it’s clear that we don’t have any CSS control over the cursor. It’s either an external resource or an icon that depends on your browser, OS, etc. This said it remains the easiest way to customize your cursor.

The Advanced Method


In this method, we are still going to use the cursor property but we will introduce a bit of SVG that will help us insert our CSS. It’s a kind of CSS-in-SVG-in-CSS. I know it’s a bit confusing but you will see that the logic is pretty easy.

Since we can consider external resources, it means that we can either use an image file or an SVG file.

html {
  cursor: url("pointer.png"), auto
  cursor: url("pointer.svg"), auto
}

You can create your cursor using SVG, store it in a file and then link it within the cursor property. Below is a basic example:

I defined the SVG like below:

<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
          "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg viewBox="0 0 30 30" width="30" height="30" xmlns="http://www.w3.org/2000/svg">
  <rect x="0" y="0" width="30" height="30" fill="red" />
</svg>

You can consider any shape you want. All you need is some SVG skills or a tool that can export your creation into SVG.

Now we are going to remove the use of the external resource and embed the SVG directly into the CSS using the following code:

html {
  cursor: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="30" height="30" viewBox="0 0 30 30"><rect x="0" y="0" width="30" height="30" fill="red" /></svg>'), auto;
}

Now the SVG code is written directly into the CSS and we can easily adjust it there without the need for any external resources. All you have to do is to start the URL with data:image/svg+xml;utf8, then copy/paste your SVG code.

But we are still using SVG and not CSS to style the cursor?

True but we are not done yet! This method relies on SVG and it’s a powerful one if you have good knowledge of SVG. I highly recommend this method because SVG is more suitable to draw shapes than CSS but the CSS method we will see next is also a good one especially if you are more comfortable using CSS than SVG (like me!)

Now we are going to use something called <foreignObject> which is as SVG tag that allows us to integrate non-SVG elements within an SVG:

The <foreignObject> SVG element includes elements from a different XML namespace. In the context of a browser, it is most likely (X)HTML. ref

We can include HTML inside an SVG which means we can use CSS to style the HTML. Our previous cursor can be written like below:

html {
  cursor: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="30" height="30" viewBox="0 0 30 30"><foreignObject width="100%" height="100%"><div xmlns="http://www.w3.org/1999/xhtml" style="width:100%;height:100%;background:red;"></div></foreignObject></svg>') , auto;
}

We used the cursor property (CSS) to embed an SVG code and inside the SVG code we embedded some HTML/CSS. We have our CSS-in-SVG-in-CSS. SVG here is only used as a container for our HTML/CSS code.

In the above example, I used a single div and inline styles to make the code easier but we can have more HTML elements and also separate the CSS. You have to follow some formatting rules to make sure the code works fine:

  • You need to minify your code and avoid any line break
  • Pay attention to the use of single quotes ' and double quotes ". If you are using a single quote with url() you need to use double quotes inside the SVG and vice versa
  • You need to encode the # character. Replace all the occurrences with %23. If you want to use the color #fff it should be %23fff.
  • If you want to separate the CSS, you can embed <style> ... </style> inside <foreignObject> but you need to make it: %3Cstyle%3E ... %3C/style%3E.

I know, it’s a lot of rules to remember in addition to the complex structure but we get easily used to it with some practice. Most of the time, you will copy and paste a previous code and adjust it, that’s what I do all the time. No need to remember everything by heart. Get back here, grab the code of one cursor and adjust it to create your own cursor.

Here is a demo with different examples of cursors that use the above code:

From the basic shape to the complex one, we can have anything we want. We can even insert some text as shown in the last example. The only limit is your imagination!

I let you explore those examples and you will notice that all I am doing is writing some common CSS while respecting the same structure and the rules I listed above.

Conclusion


Customizing a cursor has no secret for you now! From using an existing image to embedding CSS inside SVG, you have plenty of ways to create your own design. There is no best method, it all depends on your need. The last one may look a bit overkill but it’s a good exercise to practice with some SVG while still using CSS.

Temani Afif
About the Author
Temani Afif

Temani Afif is an expert web developer, a content creator, and a CSS addict. He is the mastermind behind css-challenges.com, css-generators.com, css-only.art, css-articles.com, and a lot of CSS stuff. He's also an active contributor at Stack Overflow answering all kinds of CSS questions.

View all posts by Temani Afif
Discount

SAVE 25% ON ALL MANAGED CLOUD SERVERS

with the discount code

SERVERS-SALE

Grab the discount
Jivo Live Chat