<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/2.1.3/TweenMax.min.js"></script>
<div class="cursor">
<div class="cursor__ball cursor__ball--big">
<svg height="30" width="30">
<circle cx="15" cy="15" r="12" stroke-width="0"></circle>
</svg>
</div>
<div class="cursor__ball cursor__ball--small">
<svg height="10" width="10">
<circle cx="5" cy="5" r="4" stroke-width="0"></circle>
</svg>
</div>
</div>
<div class="example">
<div class=white>
<a class="hoverable">I'M A LINK</a>
</div>
<div class=black>
<a class="hoverable">I'M A LINK</a>
</div>
</div>
<br><br>
<ul>
<li>Any <b><a src="#">link</a></b> will have this cursor effect applied to it automatically.</li>
<li>The effect uses blending mode difference.</li>
<li>The cursor falls back to default, and it's cancelled on small touch devices.</li>
</ul>
CSS
*,
*::before,
*::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body {
height: 100vh;
cursor: none;
margin: 0;
background: white;
}
body .cursor {
pointer-events: none;
}
body .cursor__ball {
position: fixed;
top: 0;
left: 0;
width: 50px;
height: 50px;
mix-blend-mode: difference;
z-index: 1000;
}
body .cursor__ball circle {
fill: #f7f8fa;
background-position: center center;
}
/* IRRELEVANT STYLES */
.example {
display: flex;
justify-content: center; /* Center items horizontally */
align-items: center; /* Center items vertically */
height: auto; /* Optional: full viewport height for vertical centering */
width: 100%;
}
ul {
display: block; /* Ensure the ul behaves as a block-level element */
margin: 0 auto; /* Center the ul horizontally */
padding-left: 0; /* Remove default padding on ul */
text-align: left; /* Align text inside ul items to the left */
list-style-position: inside; /* Ensure bullets are inside the content flow */
width: fit-content; /* Ensure the ul only takes up as much width as its content */
}
/* Style list items */
ul li {
list-style-type: disc; /* Use disc bullets */
margin-bottom: 10px; /* Add spacing between items */
font-family: Arial, sans-serif; /* Set a font for better readability */
font-size: 16px; /* Set a readable font size */
color: #333; /* Set a color for the text */
}
.black{
background: black;
color: white;
float: left;
margin: 50px;
padding: 50px;
}
JavaScript
// Function to check if the device is touch-based
function isTouchDevice() {
return 'ontouchstart' in window || navigator.maxTouchPoints;
}
// Function to check if the screen is small
function isSmallScreen() {
return window.innerWidth <= 768;
}
// Function to initialize or hide the cursor effect
function handleCursorEffect() {
const cursor = document.querySelector(".cursor");
// Check if cursor should be hidden
if (isTouchDevice() || isSmallScreen()) {
cursor.style.display = 'none';
return;
}
cursor.style.display = 'block'; // Show cursor if conditions are met
// Select all <a> tags
const $bigBall = document.querySelector(".cursor__ball--big");
const $smallBall = document.querySelector(".cursor__ball--small");
const $hoverables = document.querySelectorAll("a"); // Select all <a> tags
function onMouseMove(e) {
TweenMax.to($bigBall, 0.4, {
x: e.pageX - 15,
y: e.pageY - 15
});
TweenMax.to($smallBall, 0.1, {
x: e.pageX - 5,
y: e.pageY - 7
});
}
function onMouseHover() {
TweenMax.to($bigBall, 0.3, {
scale: 3,
top: 20,
left: 20
});
}
function onMouseHoverOut() {
TweenMax.to($bigBall, 0.3, {
scale: 1,
top: 0,
left: 0
});
}
document.body.addEventListener("mousemove", onMouseMove);
$hoverables.forEach(el => {
el.addEventListener("mouseenter", onMouseHover);
el.addEventListener("mouseleave", onMouseHoverOut);
});
}
// Run the cursor effect initialization when DOM is fully loaded
document.addEventListener('DOMContentLoaded', handleCursorEffect);
// Optional: Re-check cursor effect on window resize
window.addEventListener('resize', handleCursorEffect);
Please Whitelist JSFiddle in your content blocker.
Help keep JSFiddle free for always by one of two ways:
Whitelist JSFiddle in your content blocker (two clicks)
Go PRO and get access to additional PRO features →
Join the 4+ million users, and keep the JSFiddle dream alive.
Ad-free
All ads in the editor and listing pages are turned completely off.
Use pre-released features
You get to try and use features (like the Palette Color Generator) months before everyone else.
Fiddle collections
Sort and categorize your Fiddles into multiple collections.
Private collections and fiddles
You can make as many Private Fiddles, and Private Collections as you wish!
Console
Debug your Fiddle with a minimal built-in JavaScript console.