Formulaires✨ Premium

Shake Validation

Le champ e-mail tremble et passe au rouge quand l'adresse est mal formée ; le message reste affiché jusqu'à la correction et l'envoi est bloqué.

JSAnimationValidation

Mis à jour le

Cet effet fait partie d'Effect.Labs — 840 effets vanilla, une partie gratuite, une partie premium. Formulaires comprend 20 effets, dont 2 gratuits. Découvrir la catégorie →

3 exemples d'usage

Ticket de caisse par e-mail — l'écran tourné vers le client d'une boulangerie — Shake Validation exemple 1

① Ticket de caisse par e-mail — l'écran tourné vers le client d'une boulangerie

QuandAprès le paiement, l'écran de la caisse propose d'envoyer le ticket par e-mail. La cliente tape son adresse et touche « Envoyer mon ticket » : sans domaine complet (camille@courriel), le champ tremble et passe au rouge ; une fois « .fr » ajouté, le cadre devient vert et l'écran confirme l'envoi.
PourquoiAu comptoir, personne ne relit son adresse : une faute de frappe, c'est un ticket perdu et un client qui revient le réclamer. La secousse se voit de loin sur un grand écran, et le message reste affiché le temps de corriger.
RéglagesVersion empilée par défaut dans un <form>, --shkv-width:300px, --shkv-bg:transparent, --shkv-min-height:0, bouton orange --shkv-btn:#ca4c16, focus --shkv-focus:#f5a35c. Dans la capture, la frappe et le clic sont pilotés par le script de la scène.
Invitation d'un membre — une ligne sous le tableau de l'équipe — Shake Validation exemple 2

② Invitation d'un membre — une ligne sous le tableau de l'équipe

QuandL'administrateur tape l'adresse d'un collègue et appuie sur Entrée. Il manque « .io » : le champ tremble ; corrigé, il passe au vert et la personne rejoint la liste avec l'étiquette « En attente ».
PourquoiDans un outil de gestion, inviter est un geste rapide et secondaire : la variante en ligne tient sur une rangée et l'erreur s'affiche sous le champ, sans fenêtre ni rechargement.
RéglagesClasse shkv-inline sur la racine (champ et bouton côte à côte), thème clair : --shkv-text:#0f172a, --shkv-field:#fff, --shkv-border:#cbd5e1, --shkv-btn:#4f46e5, --shkv-error:#dc2626, --shkv-ok:#059669, --shkv-font-size:.8125rem. La touche Entrée est jouée par form.requestSubmit().
Mot de passe oublié — fenêtre du bas sur téléphone — Shake Validation exemple 3

③ Mot de passe oublié — fenêtre du bas sur téléphone

QuandSur mobile, l'utilisateur saisit l'adresse de son compte et touche « Envoyer le lien ». L'adresse incomplète est refusée sur place ; corrigée, elle passe et la fenêtre annonce l'envoi du lien.
PourquoiSur un petit écran, la bulle native se cache vite sous le clavier. Le cadre rouge et le message collés au champ restent visibles là où se trouve le pouce.
RéglagesPleine largeur (--shkv-width:100%) dans une feuille d’environ 165 px, --shkv-gap:30px pour que le message ne touche pas le bouton, tons sombres bleutés (--shkv-field:#1e2433, --shkv-btn:#0b7cb0, --shkv-error:#f87171). Le rond qui marque le toucher appartient à la scène, pas à l'effet.

Comment ça marche

À l'envoi (clic sur le bouton, touche Entrée ou soumission du <form> qui contient le champ), le script teste l'adresse avec la regex ^[^\s@]+@[^\s@]+\.[^\s@]+$, puis les règles natives du champ : required, type="email" et un éventuel pattern. Une adresse refusée pose is-invalid et is-shaking sur .shkv-group : cadre rouge, secousse horizontale de 0,5 s (@keyframes shkv-shake, 4 px d'amplitude) et message « Email invalide » sous le champ.

Le message ne s'efface plus au bout d'une demi-seconde : il reste jusqu'à la frappe suivante. Une adresse acceptée met le cadre en vert (is-valid), lui aussi jusqu'à la frappe suivante ; une adresse fausse tapée ensuite repasse donc bien au rouge. Chaque essai raté rejoue la secousse depuis le début.

Dans un formulaire, le bouton est un vrai type="submit". Adresse fausse : l'envoi est bloqué et la secousse remplace la bulle d'erreur du navigateur. Adresse juste : le formulaire part avec le champ name="email". Hors formulaire, le bouton et la touche Entrée lancent la même vérification sans rien envoyer.

Chaque .fx-0284-root est initialisé à part : deux champs dans la même page ne se pilotent pas entre eux, et rien n'est déclaré sur window.

Accessibilité

  • Étiquette réelle : « Adresse e-mail » dans un <label> masqué visuellement (.shkv-sr), plus autocomplete="email" pour le clavier e-mail sur mobile et le remplissage automatique.
  • Erreur reliée au champ : aria-invalid="true" et aria-describedby vers le message ; ce message vit dans une zone aria-live="assertive" et il est annoncé à chaque essai raté, pas seulement au premier.
  • Clavier et toucher : Tab atteint le champ puis le bouton (anneau :focus-visible), Entrée lance la vérification ; au doigt, le bouton répond comme au clic.
  • Mouvement réduit : sous prefers-reduced-motion: reduce, ni secousse ni glissement du message ; le cadre rouge, le message et le blocage de l'envoi restent.
  • Limite : le succès n'est signalé que par le cadre vert. Si votre page doit confirmer l'inscription, affichez un texte après l'envoi.
  • Contraste du bouton : texte blanc de 13 px sur le rouge #dc2626, 4,8:1, et 6,5:1 au survol sur #b91c1c. Mesuré dans Chromium, Firefox et WebKit. Si vous changez --shkv-btn, gardez au moins 4,5:1 avec le texte blanc.

Compatibilité navigateur

JavaScript sans dépendance (environ 3 Ko) et variables CSS. Mesuré le 08/11/2026 dans Chromium, Firefox et WebKit (Playwright) : deux copies indépendantes, envoi bloqué puis accepté dans un vrai <form>, touche Entrée, toucher à 390 px, mouvement réduit, aucune erreur. Versions tirées de @mdn/browser-compat-data : la plus récente des fonctions utilisées est :focus-visible.

Chrome 86+✓ Complet (mesuré)
Firefox 85+✓ Complet (mesuré)
Safari 15.4+✓ Complet (mesuré dans WebKit)
Edge 86+✓ Complet (moteur Chromium)
iOS Safari 15.4+✓ Non vérifié sur appareil réel
Android Chrome 86+✓ Complet (moteur Chromium)

Plus ancien (à partir de Chrome 51, Firefox 50, Safari 10, limite fixée par NodeList.forEach) : tout marche sauf l'anneau de focus du bouton. Sans JavaScript, le champ reste un type="email" requis : le navigateur montre sa propre bulle et bloque l'envoi.

Le code

Structure HTML à coller dans votre page (le CSS + JS sont inclus avec votre achat) :

index.html — structure
<div class="fx-0284-root">
  <div class="shkv-box">
    <div class="shkv-group">
      <label class="shkv-field">
        <span class="shkv-sr">Adresse e-mail</span>
        <input class="shkv-input" type="email" name="email" autocomplete="email" placeholder="Entrez un email valide" required>
      </label>
      <span class="shkv-msg" aria-live="assertive"><span class="shkv-msg-text" hidden>Email invalide</span></span>
    </div>
    <button class="shkv-btn" type="submit">Valider</button>
  </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éfautEffet
Couleurs d'état (CSS — --shkv-error, --shkv-ok, --shkv-focus sur .fx-0284-root) #ef4444 · #10b981 · #6366f1 Rouge du refus (cadre et message), vert de l'adresse acceptée, contour du champ actif.
Bouton (CSS — --shkv-btn, --shkv-btn-hover, --shkv-btn-font-size) #dc2626 · #b91c1c · .8333rem (13 px environ) Fond du bouton, fond au survol, taille du libellé. Le libellé lui-même se change dans le HTML.
Fond, texte et champ (CSS — --shkv-bg, --shkv-text, --shkv-field, --shkv-border) #0a0a0f · #fff · blanc à 5 % · blanc à 10 % Page claire : --shkv-bg:transparent; --shkv-text:#0f172a; --shkv-field:#fff; --shkv-border:#cbd5e1.
Largeur (CSS — --shkv-width) 280px Largeur maximale du bloc ; il se resserre si son conteneur est plus étroit. 100% pour occuper toute la colonne.
Hauteur du cadre (CSS — --shkv-min-height) 300px Hauteur de la zone de démonstration. Mettez 0 dans un vrai formulaire.
Taille du texte saisi (CSS — --shkv-font-size) 1rem Sous 1rem, Safari sur iPhone zoome au focus : gardez 1rem pour un formulaire mobile.
Écart champ-bouton (CSS — --shkv-gap) 16px À 30 px, le message d'erreur passe sous le champ sans toucher le bouton : utile quand le bloc fait moins de 260 px de large.
Disposition en ligne (classe shkv-inline sur .fx-0284-root) absente : bouton centré sous le champ Champ et bouton sur une même rangée, le bouton prend la hauteur du champ.
Règle de validation (JS — EMAIL et attributs du champ) regex ^[^\s@]+@[^\s@]+\.[^\s@]+$ + required Un pattern posé sur le champ (ex. pattern=".+@monentreprise\.fr") s'ajoute à la regex. Le texte d'erreur se change dans .shkv-msg-text.

FAQ

Non. Le script écoute submit en phase de capture sur le formulaire parent : adresse refusée, il appelle preventDefault() puis stopImmediatePropagation(), et vos propres écouteurs submit ne sont pas appelés. Si vous en avez déclaré un en capture avant le script, testez event.defaultPrevented ou l'attribut aria-invalid du champ.
La validation native de type="email" admet un domaine sans point (réseaux internes). La regex de l'effet exige un point après l'arobase pour attraper l'oubli le plus courant : « .fr », « .com ». Pour un intranet, retirez EMAIL.test(...) dans isValid() et gardez input.validity.valid.
Le script prépare les .fx-0284-root présents au moment où il s'exécute. Pour un bloc injecté plus tard, exécutez-le de nouveau après l'insertion : les racines déjà prêtes portent data-shkv-ready et sont ignorées, rien n'est branché deux fois.