Curseurs✨ Premium

Spotlight Cursor

Un halo indigo de 300 px — radial-gradient à 40 % d'opacité fondu à 70 % — dessiné par un ::before centré sur le pointeur en pixels, invisible au repos et fondu en 300 ms au survol. Le curseur natif reste : c'est un éclairage d'ambiance qui suit la main, pas un curseur de remplacement.

JSGradient

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

Bandeau de pied de page — « Prêt à démarrer ? » — Spotlight Cursor exemple 1

① Bandeau de pied de page — « Prêt à démarrer ? »

QuandDernière section d'une landing : titre, une phrase, un bouton. Fond noir uni.
PourquoiUn fond noir plat en bas de page est une zone morte ; le halo qui suit la souris lui donne du relief au moment où l'utilisateur hésite, sans concurrencer le bouton qui reste au-dessus du halo.
RéglagesHalo 300 px et width: 100% sur le conteneur (défauts), texte et bouton en z-index: 1.
Carte de fonctionnalité — halo contenu dans la carte — Spotlight Cursor exemple 2

② Carte de fonctionnalité — halo contenu dans la carte

QuandGrille de fonctionnalités d'un produit : une carte avec icône, titre, description.
PourquoiL'overflow: hidden du conteneur découpe le halo aux bords arrondis de la carte : la lumière semble venir de l'intérieur du composant, un rendu « verre » sans backdrop-filter.
RéglagesHalo 360 px en rgba(20,184,166,.35) (teinte du produit), conteneur en border-radius: 18px, transition .4s.
Hero technique — halo sur une grille de fond — Spotlight Cursor exemple 3

③ Hero technique — halo sur une grille de fond

QuandEn-tête d'un outil développeur : grille fine en fond, titre monospace, deux liens.
PourquoiSur une grille, le halo révèle les lignes qu'il traverse comme une lampe sur un plan : l'effet lit la structure du fond au lieu de la masquer.
RéglagesHalo 420 px, mix-blend-mode: screen sur le ::before, transition .5s, arrêt du dégradé à 60% pour un bord plus court.

Comment ça marche

Le conteneur #zone-spotlight-container (.spotlight-container) est position: relative, fond #0a0a0f, overflow: hidden. Son ::before porte tout l'effet : 300 × 300 px, background: radial-gradient(circle, rgba(99,102,241,.4) 0, transparent 70%), left: var(--cursor-x, 50%), top: var(--cursor-y, 50%), transform: translate(-50%, -50%) pour le centrer sur ce point, pointer-events: none, opacity: 0 et transition: opacity .3s. Le texte .spotlight-text est position: relative; z-index: 1 pour rester au-dessus du halo.

Le JS est un seul mousemove : x = clientX − rect.left, y = clientY − rect.top, puis setProperty('--cursor-x', x + 'px') et '--cursor-y' sur le conteneur. Des pixels relatifs au conteneur (mesuré : --cursor-x: 77.7px, --cursor-y: 120px pour un pointeur à ces coordonnées). Pas de requestAnimationFrame, pas de lissage : le halo est collé au pointeur, et rien ne tourne hors survol (0 appel rAF/s mesuré). Chaque événement déplace left/top d'un pseudo-élément — un relayout limité à lui.

L'apparition est du CSS pur : .spotlight-container:hover::before { opacity: 1 }, fondu de 300 ms à l'entrée comme à la sortie. Les variables ne sont jamais remises à zéro (mesuré : 77.7px encore après la sortie) : à la prochaine entrée le halo se rallume là où il était jusqu'au premier mouvement. Le dégradé atteint transparent à 70 % du rayon de 150 px, soit ≈ 105 px : le disque visible fait environ 210 px, découpé par l'overflow: hidden aux bords du conteneur. Au cœur, rgba(99,102,241,.4) sur #0a0a0f compose #2e2f69 — 1,6:1 face au fond, une lueur, pas une lampe.

Deux points d'intégration. La règle .cursor-zone pose width: 100% : la zone remplit son parent et le halo de 300 px a la place de se déployer — sans cette largeur, dans un parent flex centré, la zone se rétracterait à celle de son texte (261 px mesurés pour un aperçu de 760 px). Aucun cursor: none : la flèche système reste visible.

Accessibilité

  • Contraste du texte : rgba(255,255,255,.7) sur #0a0a0f = 9,8:1, et 6,8:1 même au cœur du halo (fond composé #2e2f69) — lisible partout. Le .info-text à rgba(255,255,255,.5) = 5,3:1 pour 14 px, conforme.
  • Le halo lui-même fait 1,6:1 face au fond : c'est un ornement, pas un composant, et il ne doit porter aucune information (WCAG 1.4.11 ne s'applique pas tant qu'il reste décoratif). N'en faites pas l'unique indice d'une zone interactive.
  • prefers-reduced-motion : le seul mouvement autonome est le fondu de 300 ms ; le halo suit la main, il n'est pas animé. Optionnel mais propre : @media (prefers-reduced-motion: reduce) { .spotlight-container::before { transition: none } }.
  • Tactile et clavier : sur écran tactile, un tap émule mousemove et :hover — le halo s'allume au point touché et reste jusqu'au tap suivant. Au clavier, rien ne se produit. Acceptable puisque l'effet est décoratif ; s'il souligne des liens, gardez-leur un :focus-visible explicite.
  • Lecteurs d'écran : le ::before a content: "", rien n'est annoncé. Si vous placez des liens dans le conteneur, donnez-leur position: relative; z-index: 1 comme .spotlight-text pour qu'ils restent au-dessus du halo, et vérifiez que l'overflow: hidden ne rogne pas leur anneau de focus près des bords.

Compatibilité navigateur

Requiert les propriétés personnalisées CSS avec setProperty, un ::before positionné et transformé, et radial-gradient(). JS ES2015 (fonctions fléchées, const). Zéro dépendance.

Chrome 49+✓ Complet
Firefox 45+✓ Complet
Safari 10+✓ Complet
Edge 15+✓ Complet
Mobile iOS✓ Halo figé au point du tap
Android Chrome✓ Halo figé au point du tap

Sans JavaScript, le halo reste au centre (repli 50 %/50 %) et s'allume toujours au survol : une vignette statique, cohérente. Sans variables CSS (navigateurs antérieurs à 2016), left/top deviennent invalides et le pseudo-élément se place en haut à gauche du conteneur.

Le code

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

index.html — structure
<div class="cursor-zone spotlight-container" id="zone-spotlight-container">
  <span class="spotlight-text">Deplacez le curseur pour illuminer</span>
  <span class="info-text" style="color: rgba(255,255,255,0.5);">Effet spotlight CSS</span>
</div>
🔒 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
Taille du halo (CSS — ::before width/height) 300 px Diamètre de la boîte du dégradé ; le disque visible fait 70 % de cette valeur (≈ 210 px). Le translate(-50%, -50%) garde le centre sous le pointeur quelle que soit la taille.
Couleur et intensité (CSS — rgba(99,102,241,.4)) indigo à 40 % Teinte et force de la lueur au centre. .6 devient une lampe ; une couleur chaude (rgba(251,191,36,.35)) donne un projecteur de scène.
Fondu du dégradé (CSS — transparent 70%) 70 % Rayon auquel le halo s'éteint. 50% = disque compact à bord doux ; 100% = lueur qui remplit toute la boîte de 300 px.
Transition (CSS — ::before transition) opacity .3s Durée de l'allumage/extinction au survol. Ajoutez left .15s, top .15s pour un halo qui suit avec un léger retard — des pixels s'interpolent, contrairement aux pourcentages non typés.
Position de repli (CSS — var(--cursor-x, 50%)) 50 % / 50 % Où se trouve le halo avant le premier mouvement et sans JS. 0% le range dans un coin ; la valeur reste utilisée tant que le JS n'a pas écrit la variable.
Mode de fusion (CSS — ::before, à ajouter) normal mix-blend-mode: screen éclaircit ce qu'il survole (images, grilles) au lieu de poser une couche colorée ; plus-lighter pour une lueur additive plus franche.
Largeur du conteneur (CSS — .cursor-zone width) 100 % La zone prend toute la largeur de son parent. Une largeur fixe (480px) borne le halo à une carte ; évitez auto dans un parent flex centré — la zone se rétracte à la largeur de son texte (261 px mesurés sur 760) et l'overflow: hidden rogne le halo de 300 px de toutes parts.

FAQ

La règle .cursor-zone livrée pose width: 100% : la zone remplit son parent. Si elle se rétracte à la largeur de son texte, c'est que cette déclaration a été retirée ou écrasée par une règle plus spécifique — dans un parent flex centré, la zone mesure alors 261 px pour 760 px disponibles, et l'overflow: hidden coupe le halo de 300 px aux bords. Vous pouvez aussi appliquer l'effet à un bloc qui a déjà sa taille (section, carte). Les trois conditions à conserver : position: relative, overflow: hidden et une hauteur.
Oui, et sans JavaScript supplémentaire : les variables sont écrites en pixels, donc left et top reçoivent des longueurs interpolables. Ajoutez left .15s ease-out, top .15s ease-out à la transition du ::before ; le halo glisse alors vers chaque nouvelle position. Pour un lissage plus physique (facteur par frame), reprenez la boucle requestAnimationFrame de Dot Follower (fx-0197).
Le JS ne traite que #zone-spotlight-container, par id. Remplacez getElementById par document.querySelectorAll('.spotlight-container').forEach(zone => { … }) en posant l'écouteur sur chaque zone : le CSS, déjà écrit sur la classe, s'applique à toutes les instances. Chaque conteneur écrit ses propres variables, il n'y a pas de collision.