Lightning Border
Bordure électrique : un anneau violet tordu par un filtre SVG de turbulence change de forme toutes les 350 ms et respire doucement ; il s'avive au survol, au focus et au doigt.
Mis à jour le
Cet effet fait partie d'Effect.Labs — 840 effets vanilla, une partie gratuite, une partie premium. Utilitaires comprend 43 effets, dont 3 gratuits. Découvrir la catégorie →
3 exemples d'usage



Comment ça marche
La boîte .ltb-box a un bord net de 2 px #7b2ff7. Juste autour, l'anneau .ltb-ring (3 px, 6 px plus large de chaque côté, arrondi de 16 px) passe par un filtre SVG : feTurbulence fabrique un bruit (fréquence 0,05, 3 octaves) et feDisplacementMap s'en sert pour décaler chaque pixel du trait de 2 px au plus. Le trait droit devient une ligne irrégulière, comme un arc électrique.
Toutes les 350 ms, le script change la graine (seed) de la turbulence : l'éclair prend une autre forme, soit moins de trois changements par seconde. En même temps, l'opacité de l'anneau va de 0,7 à 1 et revient en 1,2 s (ltb-flicker). Le script arrête les changements de forme quand la boîte sort de l'écran (IntersectionObserver) ou quand le système demande moins de mouvement, et les reprend ensuite.
Le script donne aussi à chaque copie son propre id de filtre (ltb-filter-1, ltb-filter-2…) et y relie l'anneau : plusieurs bordures sur une page ne partagent jamais le même filtre. Au survol, au focus (:focus-within) ou à l'appui du doigt (classe ltb-on), bord et anneau passent en #a855f7 avec un halo violet de 15 à 40 px.
Accessibilité
- Clignotements mesurés : image par image, aucun pixel de la bordure ne change de luminosité plus de 2 fois par seconde (seuil WCAG 2.3.1 : 3), au repos comme à l'état actif. La version d'origine allait jusqu'à 12,5 au repos et 21 au survol, mouvement réduit compris.
- Mouvement réduit : sous
prefers-reduced-motion: reduce, la forme de l'éclair est figée et l'opacité reste à 0,8 ; plus rien ne bouge. Le réglage est suivi en direct, sans recharger la page. - Décor muet : le SVG du filtre et l'anneau portent
aria-hidden="true"; seul le contenu de la boîte est lu. - Clavier et toucher : la boîte de la démo est une
<div>, que Tab ne peut pas atteindre. Pour une carte cliquable, donnez la classeltb-boxà votre<a href>ou à votre<button>en gardant le SVG du filtre et l'anneau en premiers enfants, ou placez votre lien dans la boîte : Tab allume alors l'état actif. Sur la boîte devenue lien ou bouton, cet état remplace le contour de focus ; un lien placé dedans garde le sien. Un appui du doigt allume aussi l'état actif, dans WebKit compris. - Limite : l'éclair est une animation continue, sans bouton pause ; elle ne s'arrête qu'hors écran ou avec le réglage du système.
Compatibilité navigateur
Filtre SVG (feTurbulence, feDisplacementMap) appliqué en CSS à un élément HTML, sélecteur :is() (Chrome 88, Firefox 78, Safari 14), IntersectionObserver (Chrome 51, Firefox 55, Safari 12.1) et 2 Ko de JavaScript. Mesuré dans Chromium 151, Firefox 153 et WebKit 26.5 (Playwright) : deux copies avec deux id de filtre distincts, survol de la 2e seule, focus clavier, appui du doigt, 390 px sans débordement, mouvement réduit sans aucune animation ni changement de graine, 0 erreur. Clignotements mesurés dans Chromium sur 200 images de 20 ms.
Sans JavaScript, l'anneau garde le filtre de la première copie (#ltb-filter) avec une forme fixe et seule l'opacité respire. Sans :is(), l'état actif ne s'affiche pas mais la bordure reste.
Le code
Structure HTML à coller dans votre page (le CSS + JS sont inclus avec votre achat) :
<div class="fx-0770-root">
<div class="ltb-box">
<svg class="ltb-defs" aria-hidden="true" focusable="false">
<filter id="ltb-filter" …>
<feTurbulence … result="turb"></feTurbulence>
<feDisplacementMap in="SourceGraphic" in2="turb" …></feDisplacementMap>
</filter>
</svg>
<div class="ltb-ring" aria-hidden="true"></div>
…
</div>
</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 |
|---|---|---|
Couleur (CSS — --ltb-color) |
#7b2ff7 |
Bord net et anneau électrique au repos. |
Couleur active et halo (CSS — --ltb-color-active, --ltb-glow) |
#a855f7 et rgba(123, 47, 247, .45) |
Teinte et lueur au survol, au focus et au toucher. |
Respiration (CSS — --ltb-flicker) |
1.2s |
Durée d'un aller-retour de l'opacité entre 0,7 et 1. Ne descendez pas sous 0,7 s. |
Cadence de l'éclair (JS — STEP_MS) |
350 ms |
Temps entre deux formes. Mesuré : 2 changements de luminosité par seconde au plus à 350 ms, 2,5 à 250 ms, 3,5 à 170 ms (au-delà du seuil). Restez à 250 ms ou plus. |
Amplitude (HTML — scale de feDisplacementMap) |
4 (2 px de chaque côté) |
Plus grand, le trait se tord davantage ; à 0, il redevient droit. |
Grain (HTML — baseFrequency de feTurbulence) |
0.05 |
Plus élevé, les ondulations sont plus serrées ; plus bas, plus larges. |
État actif forcé (HTML — classe ltb-on sur .ltb-box) |
absente | Garde la bordure avivée, par exemple sur l'élément en alerte. Le script ne retire que celle qu'il a posée au toucher. |
FAQ
.fx-0770-root reçoit son propre filtre (une seule .ltb-box par racine : le script ne traite que la première), et les bordures hors écran ne changent plus de forme. Chaque bordure visible recalcule tout de même son filtre à chaque nouvelle forme : au-delà d'une dizaine à l'écran en même temps, vérifiez la fluidité sur un téléphone d'entrée de gamme.