Confetti Button
Bouton qui déclenche ~100 confettis colorés au clic : les particules jaillissent hors du bouton, tombent sous gravité et rebondissent sur canvas JS.
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
Le cadre .fx-0370-root contient un canvas positionné en dépassement (position: absolute; top: -220px; left: -180px) et un bouton. Le canvas est redimensionné en JavaScript pour couvrir une large zone autour du bouton sans agrandir le DOM : son width et height sont calculés selon le devicePixelRatio pour rester nets sur écran Retina. Le canvas porte aria-hidden="true" ; les confettis sont purement décoratifs.
Au clic sur le bouton, la fonction burst() crée ~100 objets particule avec position, vitesse, couleur et rotation aléatoires. Chaque image de requestAnimationFrame efface le canvas, applique la gravité (vy += 0.4 px/image), un rebond au sol avec amortissement (vy *= −0.5), et une légère friction horizontale. Les particules disparaissent quand leur opacité atteint zéro (elle décroît de 0,015 par image). La boucle s'arrête quand toutes les particules ont disparu. Un IntersectionObserver met la boucle en pause si le composant sort de l'écran.
Sous prefers-reduced-motion: reduce, burst() ne crée aucune particule ; le bouton reste fonctionnel mais sans animation. Le bouton lui-même possède un :focus-visible visible et est activable au clavier.
Accessibilité
- Mouvement réduit : sous
prefers-reduced-motion: reduce, aucun confetti animé n'est créé. Le bouton donne tout de même un retour visuel : son fond passe brièvement au vert pendant 1,2 s pour confirmer le clic. Aucune particule n'est dessinée. - Canvas décoratif : le canvas porte
aria-hidden="true"; les confettis ne transmettent aucune information et sont ignorés des technologies d'assistance. - Bouton natif : l'élément
<button>est focusable par Tab, activable par Entrée ou Espace, et annoncé correctement par les lecteurs d'écran. Son libellé peut être personnalisé librement. - Pas d'information réservée au visuel : la pluie de confettis est une célébration visuelle ; elle ne conditionne pas l'accès à une fonctionnalité. L'action métier (validation, inscription…) doit être confirmée par un autre moyen (message textuel, page de confirmation).
Compatibilité navigateur
Canvas 2D + 2,8 Ko de JavaScript, aucune dépendance. Les confettis sont calculés en JS pur, sans bibliothèque d'animation. IntersectionObserver est disponible depuis Chrome 51, Firefox 55 et Safari 12.1 ; sans lui, la boucle tourne aussi hors écran. devicePixelRatio disponible dans tous les navigateurs modernes. Mesuré dans Chromium 151, Firefox 153 et WebKit 26 : explosion, gravité et rebond identiques dans les trois.
Sans JavaScript, le canvas reste vide et le bouton s'affiche sans effet. Sans IntersectionObserver (navigateurs avant 2018), la boucle tourne aussi hors écran — impact CPU négligeable car la boucle s'arrête naturellement quand toutes les particules ont disparu.
Le code
Structure HTML à coller dans votre page (le CSS + JS sont inclus avec votre achat) :
<div class="fx-0370-root">
<div class="mi-confetti-scene">
<div class="mi-confetti-wrap">
<canvas class="mi-confetti-canvas" aria-hidden="true"></canvas>
<button class="mi-confetti-btn">Célébrer !</button>
</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 |
|---|---|---|
Couleurs des confettis (JS — tableau colors) |
palette festive multicolore (rouge, orange, jaune, vert, bleu, violet, rose) | Remplacez par les couleurs de votre marque. Moins de couleurs donne un rendu plus sobre ; une seule couleur crée un effet monochrome. |
Nombre de confettis (JS — count = 100) |
100 particules | Diminuez à 50 pour un effet plus léger et moins gourmand en CPU, augmentez à 200 pour une explosion plus dense. Au-delà de 300, l'impact sur les performances devient perceptible sur mobile. |
Gravité (JS — vy += 0.4) |
0,4 px/image | Diminuez à 0,2 pour des confettis qui flottent lentement, augmentez à 0,8 pour une chute rapide. La valeur est en pixels par image — sur un écran 120 Hz les confettis tombent deux fois plus vite. |
Libellé du bouton (HTML — contenu de .mi-confetti-btn) |
"Célébrer !" | Remplacez par « Je participe ! », « Terminer », « Envoyer » ou tout libellé contextuel. Le bouton garde sa taille automatiquement. |
Taille des confettis (JS — w et h des particules) |
largeur 6-10 px, hauteur 3-6 px (aléatoire) | Augmentez les valeurs maximales pour des morceaux plus grands et plus visibles ; réduisez-les pour un effet « poudre ». |
FAQ
absolute avec top: -220px; left: -180px et déborde volontairement sur les éléments voisins. C'est l'effet voulu : les confettis envahissent l'espace autour du bouton. Assurez-vous que le parent direct du composant n'a pas overflow: hidden.burst(canvas, ctx) exposée dans la portée de l'instance. Pour y accéder depuis l'extérieur, ajoutez root.dataset.burst = 'ready' dans le JS et appelez root._burst() après avoir assigné la référence lors de la création.requestAnimationFrame s'arrête et le CPU n'est plus sollicité.