Skip to main content

Don’t use custom CSS mouse cursors

I believe that letting CSS load a custom cursor was a mistake. This might seem like a niche complaint, and you know what? It is. But it’s also an important one.

One of the best things about CSS is that it lets us make websites and web apps look like anything we can dream up. One of the worst things about CSS is that it lets us make websites and web apps look like anything we can dream up.

This is to say that adding a custom cursor might seem like a fun, fancy thing to do at first, but has some serious inclusive design considerations to be aware of.

What a custom cursor isn’t

First off, I’m not talking about the ability to change a mouse cursor's state. This includes a pointing hand icon for links, resize and text entry indicators, zooming, dragging affordances, etc.

A four by two grid of CSS cursors, including OS default, text edit bar, link pointer, move, open drag hand, zoom in, column resize, and cell.

These user-facing state changes are a regular part of using your Operating System (OS), and provide a vital clue for how a piece of OS interface, or an app running in the OS can be interacted with.

The web being able to borrow these OS-level affordances is huge, in that it helps people understand how a piece of web UI can be used, even though it may not look like its OS equivalent.

What a custom cursor is

A custom cursor is when you use CSS’ URL function to load a custom cursor image. The browser will then load the cursor image and apply it in place of your OS cursor any place the cursor is declared.

Hover your cursor in this area to see a custom CSS cursor example.

I’m unsure if the ability to load a custom cursor is a 90s throwback, or an example of the web platform attempting to futureproof itself.

In my experience, custom cursors are declared on the html or body element, meaning the entire website or web app gets the custom cursor applied to it.

Where you can find custom cursors

In the past, I’d see custom cursors applied to tumblr and Myspace themes, Geocities sites, and niche software.

A stylized cursor that looks like a severed, bloody hand. Above it are menu options for 'File', 'CPU', 'View', 'Settings', and 'Misc.' Screenshot.
Shout-out to my misspent youth.

Nowadays I’ve been seeing them being applied to trendy luxury ecommerce sites with increasing frequency. It’s one of those things that you probably don’t really notice until you start actively looking, unless you’re affected by it.

Why using custom cursors is a bad idea

One of the many modifications a person can make to their OS is changing the cursor. This can include increasing its size, as well as swapping it out for a more high contrast version (why high contrast isn’t the default is a separate post unto itself).

These modifications allow a user to be able to perceive, and therefore use a cursor to interact with the OS and the apps it runs.

Windows 10.

When you override this intentional modification with a custom CSS cursor, you’re denying someone something they need for a core OS operating mechanism. For some, it could be irritating. For others it could mean it makes your website or web app completely unusable.

I can’t see it

Consider someone with low vision who needs a large, high contrast cursor. Removing it to load a custom cursor in its place means the cursor might effectively disappear.

This reason alone should be a hard stop.

I don’t know what it means

If you need another reason, consider digital literacy. People internalize difficult-to-use or broken digital experience as their own personal failings.

The cursor is a consistent experience across your entire OS, and for nearly the entire internet. Changing the cursor without notice might be just enough of a disruption that it’s the thing that makes a person abandon the experience entirely.

Abandonment stemming from something like this might seem absurd to you, but it’s a very real, very disheartening thing that happens all the time.

I can’t load it

In addition to the issues of visibility and digital literacy, you need to download a custom cursor, as well as the CSS that loads it.

Performance and inclusion are deeply intertwined. Because of that, we should be ruthless in making our payloads as small as possible.

A custom cursor will probably be a small download, sure. But given that a custom cursor invites a huge amount of usability risk, this download is unnecessary.

What about browser extensions and user stylesheets?

People may be resourceful, but you shouldn't assume they’ll always be aware or motivated enough to fix the problem you created.

So, why design anything?

Don’t be so petulant.

One of design’s primary goals is to make things usable. Choices that don’t prioritize usability mean you are practicing decoration, not design.

A considered, inclusive design enhances a digital experience for all. Custom cursors may seem like part of a considered design at first blush, but they fall apart under scrutiny.

Making the choice that something “is good enough for the majority of my users” makes sweeping assumptions about who is visiting your website or web app and why, and actively discriminates.

There are plenty of other ways to communicate the tone and mood of your website or web app’s brand, ways that do not involve indiscriminately overriding expressed preferences. If the entire experience relies on a custom cursor, I’d say the problem lies a little deeper than surface-level aesthetics.

What if my use case needs a custom cursor?

Everyone thinks they’re the exception to the rule.

If you absolutely must have a custom cursor, I would say this: Test extensively before committing to this path. Check if your custom cursor design works for:

Additionally, question the parameters of the use case itself. Can the interaction be broken down into more simplified pieces?

Shouldn’t this be a browser preference?

I think so. I also think browsers could do a lot of work in this area. Until then, it’s on us to be the responsible ones.

You can’t know

We can’t know the circumstances a person is experiencing when they use your website or web app. Because of this, it’s on us to make sure we’re proactively accommodating the widest possible range of ways people interact with technology.

Vanity is almost always at odds with user needs. While a custom CSS cursor may seem flashy and fun, consider that it may present a significant, unnecessary barrier to access.