Heartbeat
Cercle rouge de 40 px, double battement (lub-dub) : pics à 140 ms et 420 ms, ×1,3 à chaque contraction, repos de 300 ms — 60 BPM, pur CSS, zéro JavaScript.
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. Chargement comprend 29 effets, dont 4 gratuits. Découvrir la catégorie →
3 exemples d'usage



Comment ça marche
Un seul div.loader-heartbeat : 40 × 40 px, background: #ef4444 (rouge-500), border-radius: 50% pour un cercle parfait. La propriété animation est entièrement résolue dans le CSS vendu : 1s ease-in-out 0s infinite normal none running heartbeat — durée 1 s, délai nul, itérations infinies. Aucun enfant, aucun pseudo-élément, aucun JavaScript.
L'animation @keyframes heartbeat compte six étapes qui décrivent un rythme double (lub-dub) : scale(1) à 0 % → scale(1.3) à 14 % (pic du premier battement à 140 ms) → scale(1) à 28 % → scale(1.3) à 42 % (pic du second battement à 420 ms) → scale(1) à 70 % → scale(1) à 100 %. La pause de repos entre les cycles dure 300 ms (de 700 ms à 1 000 ms). À l'échelle maximale, le cercle mesure 52 × 52 px. L'interpolation ease-in-out arrondit chaque montée et descente. Le second battement a une chute plus longue (280 ms contre 140 ms pour le premier), ce qui colle au rythme cardiaque réel.
Accessibilité
- prefers-reduced-motion absent du code : vérifié sous Playwright, l'animation continue de tourner (
animationPlayState: running) lorsque la préférence est activée. Aucun@media (prefers-reduced-motion)n'est présent dans le CSS vendu. Ajoutez après le bloc.loader-heartbeat:@media (prefers-reduced-motion: reduce) { .loader-heartbeat { animation: none; } }. Le cercle rouge reste visible — indicateur statique lisible sans mouvement. - En tant qu'indicateur de chargement, cet élément n'a aucun rôle sémantique dans le code vendu : il n'y a ni
role="status", niaria-busy, niaria-live, ni texte alternatif. Les lecteurs d'écran l'ignorent. Pour signaler le chargement, enveloppez le cercle dans un<span role="status" aria-label="Chargement en cours">ou ajoutez un texte masqué visuellement (visually-hidden). - Couleur seule : l'effet repose sur la couleur rouge et le mouvement pour signaler l'activité. Vérifiez que le contexte fournit un libellé textuel ou une icône complémentaire (ex. « Envoi… ») — d'autant plus si vous modifiez la couleur. Sur un fond sombre (
#0a0a0f), le rouge#ef4444mesure 3,7:1, au-dessus du seuil de 3:1 pour les éléments graphiques. - Le code vendu inclut un bloc
.demo-previewavecbackground: #0a0a0f: ce conteneur sert uniquement à la démonstration du catalogue. L'acheteur n'a besoin que de.loader-heartbeatet de la règle@keyframes heartbeat.
Compatibilité navigateur
CSS pur : transform: scale(), border-radius, animation. Zéro JavaScript, zéro dépendance.
Sans CSS animations (navigateurs très anciens), le cercle rouge reste visible et centré — indicateur statique silencieux. border-radius: 50% est supporté depuis Chrome 4 / Firefox 4 / Safari 5.
Le code
Structure HTML à coller dans votre page (CSS + JS disponibles avec un compte premium) :
<div class="loader-heartbeat"></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 |
|---|---|---|
Durée / BPM (CSS — animation-duration: 1s) |
1 s (60 BPM) | Modifiez la valeur dans la règle .loader-heartbeat. Les keyframes restent en proportion : 14 % = 1er pic, 42 % = 2e pic, 70 % = fin du 2e battement. 0.8s → 75 BPM (effort modéré) ; 1.4s → 43 BPM (repos, attente longue) ; 0.5s → 120 BPM (alerte). |
Amplitude du battement (CSS — scale(1.3)) |
×1,3 (40 px → 52 px à chaque pic) | Aux keyframes 14 % et 42 %, remplacez 1.3. En dessous de 1.1, la pulsation devient quasi invisible ; au-delà de 1.5, le cercle risque de déborder si l'espace est compté — vérifiez overflow: hidden sur le parent. |
Taille (CSS — width/height: 40px) |
40 × 40 px | Redimensionnement direct. 18–20 px pour un bouton ; 60–80 px pour un écran de chargement pleine page. Abaissez scale à 1.2 pour les petites tailles afin de limiter le décalage visuel. |
Couleur (CSS — background: #ef4444) |
#ef4444 (rouge-500) | Remplacez la valeur hexadécimale. Le rouge code la vitalité dans ce contexte ; une couleur neutre (#6366f1) convient à un loader générique. Vérifiez le contraste 3:1 sur votre fond. |
| Rythme des battements (CSS — keyframes 14 %, 28 %, 42 %, 70 %) | 14 %→28 % (1er) · 42 %→70 % (2e) · repos 70 %–100 % | Rapprochez 14 % et 42 % (ex. 10 % / 35 %) pour un rythme précipité ; écartez-les (20 % / 55 %) pour un rythme lent et profond. La pause finale (70 %→100 %) peut être réduite à 60 %→100 % pour accélérer le cycle sans toucher à la durée. |
FAQ
border-radius: 50%) qui pulse en double battement (lub-dub) : premier pic à 140 ms, second à 420 ms, repos de 300 ms. Pour un vrai cœur, remplacez le div par un SVG ❤ ou un emoji dans un span : la règle @keyframes heartbeat et la propriété animation s'appliquent telles quelles à n'importe quelle forme.span indigo qui apparaissent et disparaissent (scale 0 → 1 → 0) en vague régulière sur 1,4 s. Heartbeat n'a qu'un seul élément rouge qui grossit et rétrécit avec un rythme asymétrique (deux battements rapprochés puis une pause de 300 ms), sans enfant, sans JavaScript. L'usage est différent : les dots conviennent à tout contexte de chargement générique ; la pulsation cardiaque signale spécifiquement l'activité dans un registre médical, vital ou émotionnel.@media (prefers-reduced-motion) (vérifié). Ajoutez après le bloc .loader-heartbeat : @media (prefers-reduced-motion: reduce) { .loader-heartbeat { animation: none; } }. Le cercle rouge reste visible — indicateur statique lisible sans mouvement. Pour un repli plus doux, substituez une opacité alternée : animation: 2s ease-in-out infinite alternate heartbeat-fade avec @keyframes heartbeat-fade { from { opacity: .4 } to { opacity: 1 } }.