Scatter to Word
Les caractères s'élancent depuis des positions aléatoires et se rassemblent en un mot avec un rebond élastique — au chargement ou au clic.
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. Texte comprend 56 effets, dont 4 gratuits. Découvrir la catégorie →
3 exemples d'usage



Comment ça marche
La fonction utilitaire splitChars(t) lit l'attribut data-text du conteneur .kt-scatter, vide son innerHTML et réinjecte un <span class="char"> par caractère. Chaque span reçoit ensuite via JS une transformation CSS inline aléatoire — translate(Xpx, Ypx) rotate(Zdeg) — sur un rayon d'environ ±200 px horizontal et ±130 px vertical, avec opacity: 0 : les lettres sont dispersées hors de leur position naturelle avant tout affichage.
L'assemblage est piloté entièrement par CSS. La règle .kt-scatter.active .char impose opacity: 1 !important et transform: translate(0, 0) rotate(0deg) !important. La déclaration transition: .8s cubic-bezier(.34, 1.56, .64, 1) propre à chaque .char pilote le mouvement — le deuxième paramètre du cubic-bezier (1,56, supérieur à 1) provoque un léger dépassement de la position cible avant stabilisation : c'est le rebond élastique, sans aucun @keyframes.
La ré-animation au clic retire la classe .active, réassigne des positions aléatoires fraîches à chaque span, puis repose .active après ~80 ms. Ce délai minimal laisse le navigateur appliquer les nouvelles transformations de départ avant de relancer la transition. Sans lui, la propriété transform n'aurait pas changé d'état et aucune nouvelle transition ne se déclencherait.
Le bundle CSS inclut plusieurs variantes texte-animation partageant le même moteur de classes : .kt-wave (flottement sinusoïdal en @keyframes), .kt-elastic (apparition par scaleY), .kt-liquid (déformation hover par lettre), .kt-whirlpool, .kt-explosion. Seule .kt-scatter est documentée ici. L'ensemble est autonome : aucun canvas, aucune dépendance externe.
Accessibilité
- prefers-reduced-motion : absent du code — la transition de 0,8 s se déclenche quel que soit le réglage système. Correctif recommandé :
@media (prefers-reduced-motion: reduce) { .kt-scatter .char { transition: none; opacity: 1 !important; transform: none !important; } } - Chaque
<span class="char">contient le caractère en texte réel, lisible par les lecteurs d'écran lettre par lettre. Pour une lecture naturelle du mot entier, ajouteraria-label="[MOT]"sur le conteneur etaria-hidden="true"sur chaque.char. - Contraste texte : blanc (
#fff) sur fond sombre (#0a0a0f) — ratio ≥ 10,5:1, très au-delà du seuil WCAG AAA (7:1). - Interaction clavier : le déclenchement au clic n'a pas d'équivalent clavier dans le code. Pour l'accessibilité, ajouter
tabindex="0"sur le conteneur et un gestionnairekeydownsur Entrée / Espace. user-select: nonesur.kt-textest approprié pour du texte purement décoratif — retirer si le mot affiché transmet une information que l'utilisateur pourrait vouloir copier.
Compatibilité navigateur
Requiert CSS Transitions et transform 2D — aucun canvas, aucune dépendance externe. Les valeurs cubic-bezier supérieures à 1 (spring easing) sont supportées par tous les navigateurs modernes depuis 2020.
Si le JS n'est pas exécuté, les <code><span class="char"></code> restent à <code>opacity: 0</code> (invisibles). Prévoir un fallback <code><noscript></code> ou afficher le mot via <code>content: attr(data-text)</code> sur le pseudo-élément du conteneur.
Le code
Structure HTML à coller dans votre page (CSS + JS disponibles avec un compte premium) :
<div class="kt-text kt-scatter" id="scatter1" data-text="VOTRE MOT">
<!-- Les <span class="char"> sont injectés par splitChars() au démarrage -->
<!-- Un seul attribut data-text suffit ; le JS gère le découpage -->
</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 |
|---|---|---|
| data-text | SCATTER | Le mot affiché — modifiez cet attribut HTML sur le conteneur .kt-scatter pour changer le mot sans toucher au JS. Peut être mis à jour dynamiquement avant de retirer puis reposer la classe .active. |
| .kt-text font-size | 2.2rem | Taille des lettres. Montez à 4–6 rem pour un usage hero plein écran, descendez à 1.4 rem pour une intégration inline dans du contenu. |
| .kt-text color | #fff | Couleur des caractères. Accepte n'importe quelle valeur CSS — pour un dégradé, appliquer background: linear-gradient(...); background-clip: text; -webkit-text-fill-color: transparent; sur .kt-text. |
| .kt-scatter .char transition-duration | 0.8s | Durée de l'animation d'assemblage. 0,5 s = vif et direct, 1,2 s = cinématique et spectaculaire. |
| cubic-bezier(.34, 1.56, .64, 1) | (spring élastique) | Courbe de l'animation. Augmentez le 2e paramètre (actuellement 1,56) pour plus de rebond ; remplacez par ease-out pour une arrivée sans dépassement ; cubic-bezier(.22, 1, .36, 1) pour un spring plus doux. |
| .kt-text letter-spacing | .02em | Espacement des lettres dans leur position assemblée. Montez à .08–.15 em pour un style display large. |
| .kt-text font-weight | 800 | Graisse de la police. 700 pour un bold normal, 900 pour un impact maximal si la police le supporte. |
| Rayon de dispersion (JS) | ±200 px / ±130 px | Les positions aléatoires de départ sont calculées sur ±200 px horizontal et ±130 px vertical dans le script d'init — réduisez à ±100 px pour un scatter compact, augmentez à ±300 px pour une explosion hors-cadre. |
FAQ
splitChars(t) comme utilitaire de découpage. L'initialisation complète — attribution des positions aléatoires, pose de .active au chargement et au clic — est câblée dans le <script data-scenes> joint aux exemples. Copiez cette logique dans votre propre script : c'est une vingtaine de lignes autonomes qui n'ont besoin d'aucune dépendance.splitChars sur chaque conteneur .kt-scatter avec un id distinct, assignez des positions aléatoires à leurs .char respectifs, puis déclenchez .active indépendamment. Les transitions CSS sont scoped au conteneur : aucune interférence entre instances.data-text, retirez .active, appelez splitChars(el) pour régénérer les spans, réassignez des positions aléatoires à chaque nouveau .char, puis reposez .active après ~80 ms. Le mot change à chaque tir sans rechargement — utile pour un quiz qui révèle un mot différent à chaque question.