Hover✨ Premium

Submit Button

Un bouton d'envoi qui se transforme en spinner circulaire pendant le chargement, puis en coche de confirmation — trois états morphiques enchaînés en CSS et JavaScript, sans rechargement de page.

CSSJSStates

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

Envoi d'un formulaire de contact — site d'un cabinet dentaire — Submit Button exemple 1

① Envoi d'un formulaire de contact — site d'un cabinet dentaire

QuandBouton Envoyer ma demande sous le formulaire de prise de rendez-vous ; au clic le bouton se transforme en spinner puis confirme en coche verte. Bouton 220×48 px.
PourquoiUn bouton qui montre visuellement la progression d'envoi rassure le patient qui attend la confirmation de son rendez-vous, sans recourir à un popup de chargement intrusif.
RéglagesBouton 220×48 px, couleur de fond en vert santé pendant le succès, libellé Votre demande a bien été envoyée affiché à côté après succès.
Soumission d'un devis en ligne — outil de configuration de store sur mesure pour un fabricant de menuiseries — Submit Button exemple 2

② Soumission d'un devis en ligne — outil de configuration de store sur mesure pour un fabricant de menuiseries

QuandDernière étape du configurateur : bouton Valider la commande ; l'animation de chargement indique que le devis est en cours de calcul.
PourquoiUn bouton qui se transforme en spinner localise l'attente sur l'élément d'envoi et évite un indicateur de chargement plein écran gênant.
RéglagesLibellé Validation en cours… pendant le chargement (mis à jour via JS avant d'ajouter .loading), couleur de fond indigo.
Création d'un compte sur une plateforme de gestion de tournois sportifs amateurs — outil de registre pour associations sportives — Submit Button exemple 3

③ Création d'un compte sur une plateforme de gestion de tournois sportifs amateurs — outil de registre pour associations sportives

QuandBouton Créer mon compte du formulaire d'inscription ; le morphing en coche verte confirme sans redirection immédiate que le compte a été créé.
PourquoiUne confirmation visuelle sur le bouton lui-même est plus sobre qu'une page de confirmation séparée pour une action légère.
RéglagesBouton 200×48 px, spinner blanc sur fond violet, coche blanche sur fond vert à l'étape succès.

Comment ça marche

La racine .fx-0363-root (250 px de haut, fond rgb(26, 26, 36)) centre un bouton .mi-submit-btn de 200×52 px. Le bouton contient trois enfants superposés : .mi-submit-text (libellé Envoyer), .mi-submit-loader (conteneur du spinner), et .mi-submit-check (SVG de la coche). En CSS, les états .loading et .success sur le bouton pilotent trois changements simultanés : la largeur (200 px → 52 px pour le spinner et la coche), le rayon de bordure (14 px → 26 px pour former un cercle), et l'opacité de chaque couche.

Le spinner .mi-submit-spinner est un div de 24 px avec une bordure dont un quart est coloré et le reste transparent ; il tourne par @keyframes miSpinnerRot (0,8 s linéaire infini). La coche est un SVG polyline dont le tracé passe de 0 % à 100 % via stroke-dashoffset et @keyframes miCheckDraw (0,3 s). La transition de forme dure 0,4 s avec ease-in-out ; la transition vers l'état coche démarre 100 ms après pour que le morphing soit terminé quand la coche apparaît.

Le script est déclenché au clic sur le bouton. Il vérifie que le bouton n'est pas déjà en chargement ou en succès, ajoute .loading et les attributs aria-busy="true" et aria-disabled="true". Après 1 500 ms, il retire .loading, ajoute .success. Après 1 800 ms supplémentaires, il retire .success et nettoie les attributs ARIA. Dans votre intégration réelle, remplacez les délais fixes par la réponse de votre appel serveur.

Accessibilité

  • Clavier : le composant est un vrai <button> ; Tab l'atteint, Espace ou Entrée le déclenche. L'état de chargement désactive le bouton via aria-disabled pour prévenir les doubles soumissions.
  • État de chargement annoncé : aria-busy="true" est ajouté pendant le chargement. Les lecteurs d'écran qui interprètent cet attribut sur un bouton annoncent que l'action est en cours ; testez avec NVDA et VoiceOver car les implémentations varient.
  • Mouvement réduit : sous prefers-reduced-motion: reduce, le morphing de forme (changements de width et border-radius) est supprimé, l'animation du spinner est arrêtée, et le tracé de la coche est instantané. L'état de chargement et de succès restent indiqués par les changements de couleur et l'apparition du spinner/de la coche.
  • Toucher : le bouton répond normalement aux événements tactiles. Sa cible de 200×52 px est large et facile à atteindre au doigt.

Compatibilité navigateur

CSS (transitions width, border-radius, opacity, animations spinner et coche) + 0,5 Ko de JavaScript (classList, setAttribute, setTimeout), aucune dépendance. Vérifié dans Chromium 151 : morphing en 3 états, aria-busy mis à jour, deux copies indépendantes, mouvement réduit sans morphing, 0 erreur. Les captures d'aperçu montrent l'animation rejouée en boucle automatique par le code de scène : ce comportement n'est pas inclus dans le code vendu.

Chrome 49+✓ Complet (mesuré)
Firefox 55+✓ Complet
Safari 9+✓ Complet
Edge 79+✓ Complet (moteur Chromium)
Mobile iOS 9+✓ Complet
Android Chrome 49+✓ Complet (moteur Chromium)

Sans JavaScript, le bouton est cliquable mais ne change pas d'état. Sans transitions CSS, les trois couches apparaissent et disparaissent instantanément sans morphing.

Le code

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

index.html — structure
<div class="fx-0363-root">
  <div class="mi-submit-scene">
    <button class="mi-submit-btn">
      <span class="mi-submit-text">Envoyer</span>
      <span class="mi-submit-loader">
        <div class="mi-submit-spinner"></div>
      </span>
      <span class="mi-submit-check">
        <svg viewBox="0 0 24 24">
          <polyline points="20 6 9 17 4 12"></polyline>
        </svg>
      </span>
    </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
Couleur du bouton au repos (CSS — background de .mi-submit-btn) Violet #6366f1 Adaptez à la couleur primaire de votre charte. La couleur de succès (.mi-submit-btn.success) et la couleur de chargement (.mi-submit-btn.loading) peuvent être modifiées indépendamment.
Durée du chargement simulé (JS — premier setTimeout) 1 500 ms Dans une intégration réelle, remplacez le setTimeout par la résolution de votre promesse réseau : appelez l'entrée en état .success dans le .then() ou le callback de succès.
Libellé du bouton (HTML — texte dans .mi-submit-text) Envoyer Remplacez par Valider, S'inscrire, Confirmer, etc. Le morphing en cercle fonctionne quelle que soit la longueur du libellé, car la largeur de départ est fixe (200 px).
Durée d'affichage de la coche (JS — deuxième setTimeout) 1 800 ms Réduisez à 1 000 ms pour un retour rapide ; augmentez à 3 000 ms pour laisser le temps à l'utilisateur de lire un message de confirmation affiché à côté.

FAQ

Dans le gestionnaire de clic, retirez les setTimeout et déclenchez votre requête (fetch, XMLHttpRequest). Dans le callback de succès, passez à l'état .success ; dans le callback d'erreur, retirez .loading et restaurez le bouton à son état initial en retirant aussi aria-busy et aria-disabled.
Oui. Le script cible chaque .fx-0363-root indépendamment. Chaque bouton a son propre cycle d'états. Lancer une soumission sur l'un n'affecte pas les autres.
Le script vérifie au début du clic si le bouton est déjà en état .loading ou .success : si oui, il ignore le clic. Combiné à aria-disabled="true", cela empêche les soumissions multiples pendant le traitement.