Curseurs✨ Premium

Glow Effect

Un orbe lumineux distinct suit le pointeur dans la zone : `mouseenter` l'affiche via `display: block`, chaque `mousemove` le repositionne avec un décalage fixe de 40 px sur chaque axe, `mouseleave` le masque — et la zone reçoit la classe `cursor-active` pour que le CSS puisse effacer le curseur natif.

JSGlow

Vous aurez accès à la démo interactive avec un compte gratuit.

Cet effet fait partie d'Effect.Labs — 811 effets vanilla, une partie gratuite, une partie premium. Curseurs comprend 26 effets, dont 1 gratuits. Découvrir la catégorie →

3 exemples d'usage

Hero dark d'une landing pour outil créatif — Glow Effect exemple 1

① Hero dark d'une landing pour outil créatif

QuandUne page d'accueil en dark mode pour un générateur de visuels, un éditeur audio ou une app de retouche où le hero concentre toute l'identité visuelle.
PourquoiRemplacer le curseur OS par un orbe lumineux dès l'entrée dans le hero pose le ton : le visiteur sait qu'il est dans un environnement conçu. L'orbe attire l'œil vers le CTA sans le souligner graphiquement.
RéglagesApplique cursor: none dans .cursor-active ; stylise #cursorGlow avec border-radius: 50%, filter: blur(20px) et une couleur assortie à ton accentuation ; garde display: none → block pour une entrée nette.
Galerie photo en noir et blanc — portfolio monochrome — Glow Effect exemple 2

② Galerie photo en noir et blanc — portfolio monochrome

QuandUn portfolio ou une galerie d'œuvres sur fond très sombre, où l'image parle seule.
PourquoiL'orbe apporte une présence lumineuse sans modifier le fond. Il suit le pointeur comme une torche dans l'obscurité — une métaphore physique qui s'adapte naturellement à la consultation d'une galerie sombre sans perturber les compositions.
RéglagesOrbe plus grand (120 × 120 px, décalage 60 px) ; couleur chaude (ambre, ivoire) en contraste avec le noir et blanc ; conserve le curseur natif pour préserver la lisibilité des textes.
Interface de jeu ou cockpit de données en dark mode — Glow Effect exemple 3

③ Interface de jeu ou cockpit de données en dark mode

QuandUn écran de jeu, un menu de sélection ou un dashboard technique dense en dark mode, où le curseur OS générique casse l'immersion ou la cohérence graphique.
PourquoiL'orbe est conçu pour se substituer au curseur, pas l'accompagner. Un réticule codé maison renforce la cohérence graphique. L'apparition binaire (<code>display: none → block</code>) colle à la rigueur d'une UI technique.
RéglagesOrbe compact (40 × 40 px, décalage 20 px) ; forme SVG inline plutôt que border-radius: 50% ; cursor: none obligatoire ; pulsation CSS légère conditionnée à prefers-reduced-motion.

Comment ça marche

L'effet sépare strictement périmètre et curseur. #zone-glow définit la scène : fond sombre, border-radius d'un rem, et surtout overflow: hidden — le délimiteur silencieux qui rogne l'orbe à ses bords sans JS supplémentaire. #cursorGlow est un élément distinct du DOM, hors du flux, display: none par défaut. C'est lui seul qui se déplace ; la zone ne bouge jamais. Ce partage des rôles distingue l'effet d'un fond en dégradé radial : pas de couche recalculée à chaque frame, un élément positionné qui suit le pointeur.

Trois écouteurs, trois rôles stricts. mouseenter exécute deux instructions : ajout de cursor-active sur #zone-glow (point d'accroche CSS pour cursor: none) puis #cursorGlow à display: block — apparition instantanée, sans fondu. mouseleave inverse la paire dans le même ordre. Entre les deux, mousemove réécrit la position à chaque événement : cursorGlow.style.left = e.clientX - 40 + 'px' et cursorGlow.style.top = e.clientY - 40 + 'px'. Deux affectations de style inline par mouvement — pas de requestAnimationFrame, pas de getBoundingClientRect(). La mise à jour est synchrone avec chaque déplacement.

clientX et clientY mesurent la position dans le viewport, pas dans la zone. Soustraire 40 px sur chaque axe centre un orbe de 80 × 80 px sur le curseur : le décalage vaut la moitié des dimensions, et #cursorGlow doit être en position: fixed pour que left: clientX − 40px soit valide quel que soit le défilement. overflow: hidden rogne l'orbe visuellement à ses bords sans qu'il soit un enfant CSS de la zone. Si tu changes la taille de l'orbe, recalcule le décalage à largeur / 2 et hauteur / 2.

Accessibilité

  • prefers-reduced-motion : aucune transition ni @keyframes dans le snippet. L'usage réel de #cursorGlow implique pourtant presque toujours un filter: blur() ou une pulsation — conditionne-les derrière @media (prefers-reduced-motion: reduce). Le repositionnement par left/top n'est pas une animation CSS et ignore les media queries de mouvement : pour les visiteurs sensibles, désactive l'écouteur mousemove quand la préférence est active.
  • L'orbe reste en display: none sur écran tactile : aucun mouseenter ni mousemove ne se déclenche en usage normal. Attention si tu appliques cursor: none dans .cursor-active : certains navigateurs hybrides envoient un événement de survol synthétique au premier tap. Conditionne l'ajout de cursor-active à matchMedia('(hover: hover) and (pointer: fine)') pour les environnements hybrides.
  • Aucun des trois écouteurs ne répond au clavier : Tab, Enter, Space fonctionnent normalement. Si tu utilises cursor: none dans .cursor-active, assure-toi que la règle disparaît dès que le pointeur quitte la zone. Définis un :focus-visible marqué sur les éléments interactifs — l'orbe glow n'est pas un substitut pour la navigation clavier.
  • #cursorGlow est purement décoratif — pas de texte, pas de rôle. Pose aria-hidden="true" dessus : un div passant de display: none à display: block peut être annoncé par certains outils d'assistance sans cet attribut. Ne porte aucune information par le glow — il est invisible pour une partie non négligeable de tes visiteurs.

Compatibilité navigateur

L'effet n'utilise que du DOM de base : getElementById, classList.add/remove, et des affectations de style.left/style.top/style.display. Pas de custom properties. Le seul plancher est syntaxique : les fonctions fléchées requièrent ES2015 — IE 11 échoue avant le premier mouseenter.

Chrome 88+✓ Complet
Firefox 87+✓ Complet
Safari 14+✓ Complet
Edge 88+✓ Complet
Mobile iOS✓ Inerte (pas de curseur)
Android Chrome✓ Inerte (pas de curseur)

Sans JavaScript, <code>#cursorGlow</code> reste en <code>display: none</code> : la zone s'affiche normalement, le curseur natif reste visible. Sur un moteur ES5, l'erreur de syntaxe stoppe le script avant toute attache d'écouteur — même repli propre. L'effet est purement additif.

Le code

Structure HTML à coller dans votre page (CSS + JS disponibles avec un compte premium) :

index.html — structure
🔒 Débloquer le code complet — à partir de 2,99 € le 1er mois

HTML + CSS + JS complet, prêt à coller — avec des centaines d'effets premium.

Personnaliser

Options passées à l'API ou attributs data-* :

Option / propriétéDéfautEffet
Décalage de centrage (40 dans le JS) 40 px — pour un orbe de 80 × 80 px La valeur 40 apparaît deux fois : e.clientX - 40 et e.clientY - 40. Elle doit valoir la moitié des dimensions. Un orbe 120 × 60 px exige des décalages dissymétriques (60 et 30). Un décalage incorrect décentre le halo et révèle la mécanique.
Bascule d'affichage (display: none → block) display: none / display: block display est binaire et ne peut pas être transitionné. Pour un fondu, remplace par opacity + visibility avec transition: opacity .2s : visibility: hidden retire l'orbe des événements pointeur pendant l'invisibilité, évitant les mousemove parasites si la zone et l'orbe se chevauchent.
Classe cursor-active sur #zone-glow classe sans style imposé par le JS Le JS ajoute et retire cursor-active en miroir de la visibilité de l'orbe ; ton CSS décide quoi en faire. Usage principal : #zone-glow.cursor-active { cursor: none } pour masquer le pointeur natif. Secondairement : changer la border-color ou déclencher une animation CSS sur le fond.
Identifiant de l'orbe (#cursorGlow) getElementById('cursorGlow') L'orbe est cherché par id au démarrage ; absent, le script s'arrête proprement (if (!cursorGlow) return). Mets l'id à jour dans le JS et le HTML. Forme, taille, couleur et animations sont entièrement dans ton CSS — le JS ne connaît que l'id, le display et les left/top.
Périmètre d'écoute (#zone-glow) div de 300 px de haut avec overflow: hidden Les trois écouteurs sont attachés à #zone-glow. Change ses dimensions ou son border-radius : overflow: hidden rogné l'orbe différemment, la mécanique JS ne change pas. Pour plusieurs zones, partage un seul #cursorGlow — voir FAQ.
Présence des écouteurs mouseenter et mouseleave les deux actifs, en miroir strict Supprimer mouseleave laisse l'orbe visible en permanence une fois entré dans la zone — pertinent si la zone couvre l'essentiel du viewport. Garder seulement mousemove sans les deux autres crée un orbe qui suit mais ne s'affiche jamais : il faut aussi passer le display initial à block.

FAQ

clientX / clientY donnent la position dans le viewport, indépendante du défilement. pageX inclurait le scroll — l'orbe dériverait vers le bas. offsetX varie selon l'élément réellement survolé : un enfant de #zone-glow provoquerait des sauts. clientX − 40 reste stable parce que #cursorGlow en position: fixed est lui aussi relatif au viewport.
display: none → block est binaire, il ne peut pas être transitionné. Pour un fondu, initialise #cursorGlow avec opacity: 0; visibility: hidden; transition: opacity .2s. Sur mouseenter, passe à opacity: 1; visibility: visible ; sur mouseleave, l'inverse. visibility: hidden préserve les dimensions de l'élément mais le retire du flux pointer-events, évitant les conflits si la zone et l'orbe se chevauchent.
Laisse un seul #cursorGlow dans le DOM et attache le même triplet d'écouteurs à chaque zone : l'orbe apparaît et se repositionne dans celle où le pointeur entre, disparaît au mouseleave. Si les zones ne se chevauchent pas, la transition est naturelle. En cas de chevauchement, un compteur de zones actives évite que le mouseleave de l'une masque l'orbe entré dans l'autre.