Did you know that if you add this little snippet of code to your website, you can replace your mouse cursor with pretty much anything?
button:hover {
cursor: url("cursor.png"), pointer;
}
Instead of the default arrow, you can turn it into an emoji, an icon, or a tiny custom graphic. That comma before pointer matters. The browser tries to load cursor.png first. If it fails, or the browser doesn't support custom cursors, it falls back to the normal pointer. Never skip that fallback.
Each element below is fully interactive. Hover over any of them and watch the cursor change on the spot.
I wouldn’t recommend replacing the cursor for your entire website. Keep it close to what people already expect. But scoped to one interaction, at one moment, it turns something completely ignored into a small detail people notice. Here’s where it actually earns its place.
Say what the click does, not just that it's clickable
A pointer only tells someone "this is interactive." A custom cursor can tell them what interacting does.
.zoom-image:hover {
cursor: url("magnifier.png") 12 12, zoom-in;
}
.crop-tool:hover {
cursor: url("scissors.png") 4 4, crosshair;
}
.drag-card:hover {
cursor: grab;
}
.drag-card:active {
cursor: grabbing;
}
Those two numbers after the URL, 12 12and 4 4, set the cursor's hotspot. That's the exact pixel inside your image that lines up with the actual click point. Skip them and the browser defaults to the top left corner of the image, which looks wrong almost every time, especially on anything shaped like scissors or a pointing hand.
Add a bit of personality to your main call to action
This is the fun one. Swap the cursor for a tiny branded icon right on the button you most want someone to click.
.cta-button:hover {
cursor: url("rocket.png") 4 4, pointer;
}
You don't even need an image file for this. An SVG data URI does the same job with zero extra requests:
.like-button:hover {
cursor: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32"><text y="24" font-size="24">❤️</text></svg>') 16 16, pointer;
}
It's one line, nothing to host, and the emoji scales cleanly since it's just text sitting inside SVG markup.
Give portfolios and case studies a signature feel
Designers and agencies get away with a lot more here, because a custom cursor reads as craft instead of gimmick when the whole site is already built around visual work.
.project-thumb:hover {
cursor: url("view-pill.png") 30 10, pointer;
}
A small pill-shaped cursor that says "View" while hovering a thumbnail does more work than a caption ever could. People move their mouse before they read anything.
Turn it into a small warning
Right before a destructive action, a cursor change adds one extra beat of friction.
.delete-account-btn:hover {
cursor: url("warning.png") 12 12, not-allowed;
}
The person still has to move their mouse over the button and register that something changed. That half second is sometimes enough to make them pause and reconsider.
Build a world for exploration-based sites
Interactive stories, narrative scrollers, and portfolio sites built around a theme can carry that theme into the cursor itself.
.map-section:hover {
cursor: url("compass.png") 16 16, pointer;
}
.dark-mode .story-panel:hover {
cursor: url("torch.png") 8 24, pointer;
}
It's a small thing, but it reinforces that the visitor is inside something built with intention, not just scrolling a normal page.
Keep these rules in mind
Size your cursor images small. Most browsers cap custom cursors around 128x128 pixels, and anything bigger gets ignored or scaled down badly. 32x32 or 48x48 is usually the sweet spot.
Always include a fallback keyword after your URL, whether that's pointer, grab, zoom-in, or not-allowed. Some browsers and some users won't load the custom image at all, and you don't want the button falling back to nothing.
And keep it local. One button, one thumbnail, one section. The moment your entire site runs on a custom cursor, it stops feeling like a surprise and starts feeling like a bug.
Happy designing.
Did you learn something good today as a developer?
Then show some love.
© Muhammad Usman
Don’t forget to subscribe to Developer’s Journey to show your support.







Top comments (0)