Back to Blog
Basic Custom Cursor Using CSS Only (No JavaScript)
A practical guide to building a basic custom cursor using pure CSS—no JavaScript involved—including plain CSS and Tailwind CSS approaches, with clear real-world limitations.
Back
Frontend

Table of contents
Before talking about animations, inertia, or fancy trailing effects, it’s important to understand the hard limits of custom cursors on the web:
CSS can change the cursor’s appearance, but not its behavior.
That means:
- CSS cannot track mouse movement freely
- CSS cannot create trailing or easing effects
- CSS cannot build interactive or animated cursors
But CSS is perfect for:
- replacing the default cursor icon
- defining consistent hover states
- lightweight branding
- accessibility-safe customization
This article focuses strictly on basic, CSS-only custom cursors.
Try it live: View Demo | Download HTML (right-click → Save As)
Core Concept: Custom Cursors in CSS
CSS exposes a single property for this:
css
cursor: ...;The value can be:
- a built-in keyword (
pointer,grab, etc.) - a custom image via
url(...) - a fallback cursor
The simplest example:
css
body {
cursor: pointer;
}This is rarely recommended, but it illustrates the idea.
Custom Cursor with an Image (CSS Only)
This is the most common and production-safe way to build a custom cursor using CSS.
1) Prepare the Cursor Asset
Recommended specs:
- Format:
pngorsvg - Ideal size: 32×32 px (max 128×128)
- Transparent background
Example file name: cursor-dot.png
2) Apply the Cursor in CSS
css
body {
cursor:
url('/cursor-dot.png') 16 16,
default;
}Explanation:
16 16defines the hotspot (click position)defaultacts as a fallback
3) Different Cursor on Hover
css
a,
button {
cursor:
url('/cursor-hover.png') 16 16,
pointer;
}This is pure CSS, zero JavaScript, and extremely stable in production.
Minimal Editorial-Style Cursor Example
css
body {
cursor:
url('/cursor-dot.svg') 8 8,
default;
}
a:hover,
button:hover {
cursor:
url('/cursor-ring.svg') 12 12,
pointer;
}This style works well for:
- blogs
- landing pages
- portfolios
Honest Limitations of CSS-Only Cursors
With CSS alone, you cannot:
❌ Create trailing effects
❌ Add easing or interpolation
❌ Follow real-time pointer position
❌ Build context-aware cursor behavior
With CSS alone, you can:
✅ Customize cursor visuals
✅ Define hover affordances
✅ Maintain visual consistency
✅ Avoid performance overhead
If you need behavior, JavaScript is not optional.
Custom Cursor with Tailwind CSS (CSS-Only)
Tailwind does not extend cursor capabilities—it only changes how you author styles.
1) Using Arbitrary Values
html
<div class="cursor-[url('/cursor-dot.png')_16_16,_default]">Content</div>Hover state:
html
<a
class="cursor-[url('/cursor-dot.png')_16_16,_default]
hover:cursor-[url('/cursor-ring.png')_16_16,_pointer]"
>
Link
</a>Note: underscores (
_) represent spaces
2) Recommended Tailwind Best Practice
Define reusable cursor utilities instead of cluttering markup.
tailwind.config.js
js
module.exports = {
theme: {
extend: {
cursor: {
dot: "url('/cursor-dot.png') 16 16, default",
ring: "url('/cursor-ring.png') 16 16, pointer",
},
},
},
};Usage
html
<body class="cursor-dot">
<a class="hover:cursor-ring">Link</a>
<button class="hover:cursor-ring">Button</button>
</body>This approach is clean, reusable, and scalable.
Accessibility Considerations (Do Not Skip)
Always account for non-mouse input:
css
@media (pointer: coarse) {
body {
cursor: auto;
}
}Avoid:
- overly small cursors
- incorrect hotspots
- low-contrast designs
The cursor is a navigation tool—not decoration.
When CSS-Only Is Enough
CSS-only cursors make sense when:
- you do not need animation
- branding is minimal
- the site is mostly static
- performance risk must be zero
Use JavaScript when:
- motion matters
- interaction is contextual
- cursor behavior changes dynamically
Try It Yourself
A complete, standalone HTML demo is available:
- View Live Demo: See the CSS-only cursor in action
- Download HTML File: Right-click and "Save As" to get the complete code
The demo file shows both plain CSS and data URI implementations. You can open it directly in your browser or use it as a reference for your own projects.
Conclusion
CSS-only custom cursors are simple, honest, and reliable.
They do one thing well: replace the cursor visually without introducing performance or maintenance risk. For many editorial sites and landing pages, this is exactly the right level of customization.
If you need more than this, that's not a limitation of CSS—it's a signal that JavaScript belongs in the solution.
Comments
No comments yet
Loading comments...