interactions · curseur
Remplace le curseur natif par un cercle qui suit la souris et change d'aspect selon l'élément survolé (lien, zone de drag...). Nécessite du JavaScript.
<style>
.bn-cursor-zone {
position: relative;
min-height: 260px;
overflow: hidden;
padding: 3rem;
font-family: 'Inter', sans-serif;
background: #0B0F10;
/* On masque le curseur natif du navigateur DANS cette zone
uniquement — c'est ce qui rend le curseur personnalisé crédible */
cursor: none;
}
.bn-cursor-zone__hint {
color: #979793;
font-size: 0.85rem;
margin: 0 0 2rem;
}
.bn-cursor-zone__row {
display: flex;
gap: 1.5rem;
}
.bn-cursor-zone__link {
color: #E6E4DD;
text-decoration: underline;
font-size: 0.9rem;
}
.bn-cursor-zone__drag {
padding: 0.6rem 1.2rem;
border: 1px solid rgba(230, 228, 221, 0.3);
border-radius: 999px;
background: none;
color: #E6E4DD;
font-size: 0.85rem;
}
.bn-custom-cursor {
position: absolute;
top: 0;
left: 0;
width: 20px;
height: 20px;
border: 1px solid #E6E4DD;
border-radius: 50%;
pointer-events: none;
transform: translate(-50%, -50%);
/* Se déplace en douceur plutôt que de suivre pile la souris —
donne un effet plus organique */
transition: width 0.2s ease, height 0.2s ease, background 0.2s ease,
transform 0.08s linear;
opacity: 0;
}
.bn-cursor-zone:hover .bn-custom-cursor {
opacity: 1;
}
/* États : grandit et se remplit selon l'élément survolé */
.bn-custom-cursor.is-over-link {
width: 44px;
height: 44px;
background: rgba(230, 228, 221, 0.15);
}
.bn-custom-cursor.is-over-drag {
width: 56px;
height: 56px;
background: #E6E4DD;
border-color: transparent;
}
</style>
<div class="bn-cursor-zone" data-fx-root>
<p class="bn-cursor-zone__hint">Déplacez votre souris dans cette zone.</p>
<div class="bn-cursor-zone__row">
<a href="#" class="bn-cursor-zone__link" data-cursor="link">Un lien</a>
<button type="button" class="bn-cursor-zone__drag" data-cursor="drag">Zone "drag"</button>
</div>
<!-- Le curseur personnalisé lui-même : un simple rond positionné
en absolu, déplacé par script.js pour suivre la souris -->
<div class="bn-custom-cursor" data-custom-cursor></div>
</div>
<script>
/* ==========================================================
CURSEUR PERSONNALISÉ
Un rond suit la souris à l'intérieur de la zone (dont le curseur
natif est masqué en CSS), et change de taille/couleur selon
qu'il survole un lien, une zone "drag", ou rien de particulier.
========================================================== */
(function () {
const zone = document.querySelector('.bn-cursor-zone[data-fx-root]');
if (!zone) return;
const cursor = zone.querySelector('[data-custom-cursor]');
zone.addEventListener('mousemove', (event) => {
const rect = zone.getBoundingClientRect();
cursor.style.transform = `translate(${event.clientX - rect.left}px, ${event.clientY - rect.top}px) translate(-50%, -50%)`;
});
zone.querySelectorAll('[data-cursor]').forEach((el) => {
el.addEventListener('mouseenter', () => {
cursor.classList.add(`is-over-${el.dataset.cursor}`);
});
el.addEventListener('mouseleave', () => {
cursor.classList.remove(`is-over-${el.dataset.cursor}`);
});
});
})();
</script>