Magnetic Letters
Huit lettres sur fond sombre dérivent vers le curseur quand il s'approche à moins de 100 px, puis reviennent élastiquement à leur place ; un clic inverse la direction et les repousse. La force est proportionnelle à la distance — plus le curseur est proche, plus l'attraction (ou la répulsion) est forte.
Mis à jour le
Cet effet fait partie d'Effect.Labs — 840 effets vanilla, une partie gratuite, une partie premium. Hover comprend 48 effets, dont 5 gratuits. Découvrir la catégorie →
3 exemples d'usage



Comment ça marche
Chaque lettre est un <span class="ml379-letter"> dans le conteneur .ml379-container. À chaque image d'une boucle requestAnimationFrame, le script calcule la distance entre le centre de chaque lettre et la position de la souris dans le repère du conteneur. Si cette distance est inférieure à 100 px, la lettre est décalée par un translate(dx, dy) dont l'amplitude vaut distance × force × 0,5 × direction : force vaut (100 − dist) / 100, donc 1 au centre et 0 à 100 px. La direction vaut +1 (attraction) ou −1 (répulsion) selon l'état courant, basculé à chaque clic sur le conteneur. Si la souris est à plus de 100 px ou hors du conteneur, la lettre retrouve translate(0, 0) par la propriété CSS transition: transform 0.1s ease-out.
La couleur de la lettre passe de #6366f1 (au repos) à hsl(280 + i × 15, 70 %, 60 %) quand elle est dans la zone d'influence, avec i son rang dans la liste (du violet au rose). Quand le curseur quitte le conteneur, l'événement mouseleave remet toutes les lettres en place instantanément. L'événement touchmove (avec preventDefault()) fournit le même comportement au doigt. Un IntersectionObserver met la boucle en pause quand l'effet n'est pas visible.
Accessibilité
- Rôle et label : le conteneur porte
role="img"etaria-label="MAGNETIC"; les huit lettres ontaria-hidden="true". Un lecteur d'écran lit « MAGNETIC » une seule fois et ignore le mouvement des lettres. - Focus clavier : le conteneur a
tabindex="0"et un contour:focus-visible(2 px indigo). Au focus, la souris est virtuellement placée au centre du conteneur, ce qui déclenche l'attraction sur les lettres du milieu ; au blur, les lettres reviennent à leur place. - Toucher :
touchmovedéplace les lettres vers le doigt exactement comme la souris.touchendremet les lettres en place. Le comportement de défilement de la page est bloqué (preventDefault) tant que le doigt est dans le conteneur. - Mouvement réduit : sous
prefers-reduced-motion: reduce, la boucle ne démarre pas et la propriété CSStransition: noneest forcée sur les lettres ; les lettres restent fixes, le label est toujours lisible. - Clic : le clic inverse le mode attraction ↔ répulsion. Aucun rôle de bouton n'est ajouté sur le conteneur (
role="img"reste prioritaire) ; si l'alternance est fonctionnelle dans votre contexte, remplacez le role parrole="button"et ajoutez un gestionnairekeydownsur Entrée/Espace.
Compatibilité navigateur
DOM pur et CSS, aucune dépendance. IntersectionObserver disponible depuis Chrome 51, Firefox 55, Safari 12.1. requestAnimationFrame depuis Chrome 10, Firefox 11, Safari 6. Les transitions CSS et window.matchMedia couvrent tous les navigateurs modernes. Non vérifié sur Safari réel ; attendu complet.
Sans JavaScript, les lettres s'affichent fixes sans aucun comportement. Sans IntersectionObserver, la boucle tourne aussi hors écran.
Le code
Structure HTML à coller dans votre page (le CSS + JS sont inclus avec votre achat) :
<div class="fx-0379-root">
<div class="ml379-container" role="img" aria-label="MAGNETIC" tabindex="0">
<span class="ml379-letter" aria-hidden="true">M</span>
<span class="ml379-letter" aria-hidden="true">A</span>
<span class="ml379-letter" aria-hidden="true">G</span>
<span class="ml379-letter" aria-hidden="true">N</span>
<span class="ml379-letter" aria-hidden="true">E</span>
<span class="ml379-letter" aria-hidden="true">T</span>
<span class="ml379-letter" aria-hidden="true">I</span>
<span class="ml379-letter" aria-hidden="true">C</span>
</div>
<span class="ml379-label" aria-hidden="true">Approchez la souris des lettres</span>
</div>
Paiement unique, sans abonnement — le code est à toi pour toujours
Personnaliser
Options passées à l'API ou attributs data-* :
| Option / propriété | Défaut | Effet |
|---|---|---|
Rayon d'influence (JS — if(dist < 100)) |
100 px | 60 px donne un effet plus précis et moins envahissant ; 150 px attire les lettres depuis la moitié du conteneur. |
Intensité du déplacement (JS — force * 0.5) |
0,5 | 0,8 rend le déplacement plus spectaculaire ; 0,2 donne un souffle à peine perceptible. |
Mode par défaut (JS — var isAttract = true) |
attraction | Initialisez à false pour démarrer en répulsion. |
Texte des lettres (HTML — huit <span class="ml379-letter">) |
MAGNETIC (8 lettres) | Remplacez par n'importe quel mot de 4 à 12 lettres ; au-delà de 10, réduisez la police à 1,8 rem pour éviter le débordement sur mobile. |
Vitesse de retour (CSS — transition: transform 0.1s) |
0,1 s | 0,3 s donne un retour paresseux ; 0,04 s un snap quasi immédiat. |
FAQ
role="img" par role="button", ajoutez aria-label="Basculer attraction / répulsion" et un gestionnaire keydown qui appelle le basculement sur Entrée et Espace. Vérifiez que le contour :focus-visible reste visible.span.ml379-letter qu'il trouve dans le conteneur. Sur mobile à 390 px, 10 lettres en 2,5 rem tiennent sur une ligne sans déborder ; au-delà, le flex-wrap les fait passer à la ligne, ce qui décale les centres et donne un effet à deux niveaux.