Spotlight Effect
Un ::before suivi par le curseur via deux propriétés CSS crée un halo lumineux sur la carte — dégradé radial, transition d'opacité, zéro canvas.
Mis à jour le
Cet effet fait partie d'Effect.Labs — 840 effets vanilla, une partie gratuite, une partie premium. Cartes comprend 43 effets, dont 6 gratuits. Découvrir la catégorie →
3 exemples d'usage



Comment ça marche
Le cœur de l'effet est le pseudo-élément .card-spotlight::before, dimensionné à 200 × 200 px et positionné en absolute. Sa propriété left: var(--spotlight-x, 50%) et top: var(--spotlight-y, 50%) couplée à transform: translate(-50%, -50%) le centre exactement sur le curseur. Son remplissage est un dégradé radial : radial-gradient(circle, rgba(99,102,241,.5) 0, transparent 70%) — indigo saturé au centre, totalement transparent à 70 % du rayon. La carte porte overflow: hidden pour clipper le halo à ses bords.
La mise à jour de position est synchrone et directe : à chaque événement mousemove, le JS appelle getBoundingClientRect() sur la carte pour convertir les coordonnées viewport (clientX, clientY) en coordonnées relatives à la carte, puis les pousse avec style.setProperty('--spotlight-x', …) et style.setProperty('--spotlight-y', …). Aucun requestAnimationFrame n'est nécessaire — la mise à jour suit le curseur pixel par pixel sans décalage.
L'apparition et la disparition du spot sont gérées par :hover et une transition d'opacité : opacity: 0 par défaut, opacity: 1 sur .card-spotlight:hover::before, avec transition: opacity .3s. Sans ce fondu, le spot surgirait brusquement à l'entrée du pointeur même si les variables CSS sont déjà positionnées correctement.
Accessibilité
- prefers-reduced-motion absent dans ce code — la transition d'opacité 0,3 s joue quelles que soient les préférences système. Correctif recommandé :
@media (prefers-reduced-motion: reduce) { .card-spotlight::before { transition: none; } }. - L'effet est purement décoratif : il ne modifie ni le contenu ni la structure sémantique de la carte — aucun impact sur les lecteurs d'écran.
- Activation au
:hoveruniquement, pas au:focus. Pour les utilisateurs clavier, ajouter.card-spotlight:focus-within::before { opacity: 1; }. - Contraste du contenu : fond
#12121aavec texte blanc — ratio supérieur à 10:1, conforme WCAG AA et AAA. - Aucun mouvement continu : pas de RAF, pas d'animation CSS en boucle — l'effet n'est actif que pendant les déplacements réels du curseur.
Compatibilité navigateur
Requiert les propriétés CSS personnalisées (var()) et les pseudo-éléments — disponibles dans tous les navigateurs modernes. Zéro dépendance externe.
Sans support des propriétés CSS personnalisées, le spot reste fixe au centre de la carte (valeur de repli 50% définie dans le CSS) — reflet statique, aucune erreur JS.
Le code
Structure HTML à coller dans votre page (le CSS + JS sont inclus avec Premium) :
<div class="card-demo card-spotlight" id="spotlightCard">
<h3 class="card-title">Titre</h3>
<p class="card-body">Contenu de la carte</p>
</div>
Le code complet HTML + CSS + JS de Spotlight Effect, prêt à coller — et les 840 effets. Ou 299 € TTC une fois, accès à vie.
Personnaliser
Options passées à l'API ou attributs data-* :
| Option / propriété | Défaut | Effet |
|---|---|---|
| Couleur du spot | rgba(99, 102, 241, .5) | Première valeur dans radial-gradient(circle, COULEUR 0, transparent 70%) du sélecteur .card-spotlight::before. Toutes les syntaxes CSS sont acceptées (rgba, hsl, hex). |
| Taille du spot (width / height) | 200px | Dimensions du ::before. Augmenter (300–400 px) pour un halo diffus sur grandes cartes ; réduire (120 px) pour un faisceau concentré. |
| Rayon de transparence (falloff) | 70% | Second paramètre de radial-gradient(circle, … 0, transparent 70%). Plus bas (50 %) = bord plus net ; plus haut (85 %) = halo très doux. |
| Durée de transition | 0.3s | La propriété transition: opacity .3s sur .card-spotlight::before. 0 s = apparition instantanée ; 0,8 s = fondu lent cinématique. |
| --bg-card | #12121a | Variable CSS du fond de carte. À surcharger sur l'élément : style="--bg-card: #1e1b4b". |
| --radius-xl | 1rem | Rayon d'arrondi appliqué via border-radius: var(--radius-xl) sur la carte. |
FAQ
mousemove et :hover reste inactif : le spot reste invisible. Pour une version tactile, écouter touchmove en parallèle et appeler les mêmes style.setProperty() sur les coordonnées touch.getElementById('spotlightCard') — un seul élément. Pour une grille, remplacer par document.querySelectorAll('.card-spotlight') et boucler : els.forEach(el => el.addEventListener('mousemove', e => { const r = el.getBoundingClientRect(); el.style.setProperty('--spotlight-x', (e.clientX-r.left)+'px'); el.style.setProperty('--spotlight-y', (e.clientY-r.top)+'px'); }));--spot-color: rgba(99,102,241,.5) dans .card-spotlight::before et l'utiliser dans le dégradé, puis surcharger : .card-spotlight.is-danger { --spot-color: rgba(239,68,68,.5); } — la couleur change sans toucher au JS.