Spotlight Follow
Pseudo-élément CSS + deux custom properties : le halo indigo de 400 px suit le curseur en temps réel, révélant le fond sans canvas ni librairie externe.
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. Backgrounds comprend 50 effets, dont 6 gratuits. Découvrir la catégorie →
3 exemples d'usage



Comment ça marche
L'effet repose entièrement sur un pseudo-élément ::before rattaché au conteneur .bg-spotlight. Ce pseudo-élément porte un radial-gradient(circle, rgba(99,102,241,.3) 0, transparent 70%) sur une surface de 400×400 px — un cercle indigo translucide à 30 % d'opacité qui s'estompe à 70 % du rayon, sans jamais masquer le fond.
Le positionnement du halo passe par deux CSS custom properties : --mouse-x et --mouse-y. Le ::before déclare left: var(--mouse-x, 50%) et top: var(--mouse-y, 50%) — les valeurs par défaut (50%) centrent le halo avant tout déplacement de souris. Le pseudo-élément est décalé par transform: translate(-50%, -50%) pour que son centre, et non son coin supérieur gauche, suive le curseur.
Le JS écoute mousemove sur le conteneur, calcule la position du curseur en pourcentage de la BoundingClientRect de l'élément ((e.clientX - rect.left) / rect.width * 100), puis écrit les valeurs via el.style.setProperty('--mouse-x', x + '%'). Le navigateur applique immédiatement les nouvelles custom properties au ::before — aucun requestAnimationFrame, aucun canvas, zéro layout shift.
pointer-events: none sur le pseudo-élément garantit que le halo n'intercepte jamais les clics ni le survol des éléments enfants. La propriété transition: opacity .3s sur le ::before est prévue pour adoucir une apparition/disparition pilotée en JS — elle n'anime pas la position (le déplacement du halo est délibérément instantané).
Accessibilité
- prefers-reduced-motion : absent du code source — le halo suit le curseur quel que soit le réglage OS. Pour les utilisateurs sensibles, ajoutez
@media (prefers-reduced-motion: reduce) { .bg-spotlight::before { display: none; } }. - Aucun
aria-hidden,roleniaria-labelsur le conteneur dans le code de base — ajoutezaria-hidden="true"si le spotlight est purement décoratif, ourole="img"+aria-labeldescriptif s'il constitue le décor principal d'une section. - Le contenu textuel placé à l'intérieur du conteneur (ex.
.bg-label) reste accessible aux lecteurs d'écran — le halo CSS ne touche pas au DOM. pointer-events: nonesur le pseudo-élément empêche le halo d'intercepter le focus clavier ou les clics sur les éléments enfants.- Sur mobile / écran tactile,
mousemoven'est pas déclenché au toucher : le halo reste à sa position par défaut (centre) — comportement dégradé visuel sans erreur JS.
Compatibilité navigateur
Nécessite les CSS Custom Properties et les pseudo-éléments — supportés dans tous les navigateurs modernes. Zéro dépendance externe, zéro Canvas.
Sur les anciens navigateurs sans support des CSS Custom Properties (IE), le <code>::before</code> reste à sa position par défaut — le halo centré est visible, sans erreur JS.
Le code
Structure HTML à coller dans votre page (CSS + JS disponibles avec un compte premium) :
<div class="bg-spotlight" id="spotlightBg">
<!-- Votre contenu : titre, bouton, image -->
<span class="bg-label">Votre titre</span>
</div>
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éfaut | Effet |
|---|---|---|
| rgba(99, 102, 241, .3) | indigo à 30 % | Couleur et intensité du halo — remplacez R/G/B et l'alpha (0,1 = très discret, 0,5 = marqué). Exemple brand bleu : rgba(59,130,246,.35). |
| width / height du ::before | 400 px | Diamètre du cercle de lumière — augmentez à 600–700 px pour un hero plein écran, réduisez à 200 px pour une carte de grille. |
| transparent 70% | 70 % | Arrêt transparent du dégradé — 50 % = halo net et concentré, 85 % = halo très diffus et enveloppant. |
| transition: opacity .3s | 0,3 s | Durée du fondu d'opacité — passez à 0 s pour une réponse instantanée, ou pilotez opacity via JS pour un fade-in à l'entrée de la souris. |
| --mouse-x / --mouse-y (valeur initiale) | 50 % | Position de repos du halo avant le premier déplacement de souris — changez à 20% / 80% pour décaler le point de départ. |
| background du .bg-spotlight | #0a0a0f | Fond du conteneur — adaptez à votre page (#111827, #1e1b4b, transparent si le spotlight est en superposition sur une image ou une vidéo). |
FAQ
getElementById('spotlightBg') — un seul élément. Pour plusieurs instances, remplacez-le par une boucle sur la classe : document.querySelectorAll('.bg-spotlight').forEach(function(el){ el.addEventListener('mousemove', function(e){ var r=el.getBoundingClientRect(); el.style.setProperty('--mouse-x',((e.clientX-r.left)/r.width*100)+'%'); el.style.setProperty('--mouse-y',((e.clientY-r.top)/r.height*100)+'%'); }); }). Le CSS fonctionne déjà sur plusieurs éléments .bg-spotlight.mousemove n'est pas déclenché. Le halo reste centré à sa position par défaut (50% / 50%) — comportement neutre sans erreur. Pour une interactivité tactile, ajoutez un listener touchmove et utilisez e.touches[0].clientX/Y à la place des coordonnées souris.radial-gradient(circle, rgba(99,102,241,.3) 0, transparent 70%). Remplacez 99,102,241 par votre couleur brand en RGB — ex. bleu 59,130,246, violet 139,92,246, rouge 239,68,68 — et ajustez l'alpha (0,3 par défaut) pour contrôler l'intensité du halo.