spb/svgarden Public
SVGarden — searchable bank of 74 self-contained SVG+CSS animation snippets (svgarden.dev)
HTML 79.2%
Astro 10.3%
JavaScript 6%
CSS 3.7%
Shell 0.8%
1<!--2 ============================================================3 SVGarden — https://www.svgarden.dev4 Author : Simon-Pierre Boucher5 Contact: contact@spboucher.ai6 File : snippets/loaders/dots-pulse.html7 Desc : Three SVG circles pulsing in sequence8 ============================================================9-->10<!--svgarden11title: Pulsing dots12slug: dots-pulse13category: loaders14tags: [loader, dots, stagger, keyframes]15difficulty: beginner16techniques: [animation-delay, transform-box, scale, opacity]17how_it_works: >18 All three circles share one shrink-and-fade keyframe animation; the wave19 illusion is pure timing — each dot starts a third of the duration later20 than its neighbor via animation-delay. transform-box: fill-box makes each21 circle scale around its own center instead of the SVG's origin, which is22 the classic gotcha when transforming SVG elements with CSS.23customizable:24 - { var: "--sg-color", label: "Color", type: color, default: "#7F77DD" }25 - { var: "--sg-size", label: "Size", type: range, min: 32, max: 160, default: 64, unit: px }26 - { var: "--sg-duration", label: "Speed", type: range, min: 0.4, max: 3, step: 0.1, default: 1.2, unit: s }27created: 2026-08-1028-->29<div class="sg-dots-pulse" style="--sg-color:#7F77DD; --sg-size:64px; --sg-duration:1.2s;">30 <svg viewBox="0 0 60 20" aria-hidden="true" focusable="false">31 <circle cx="10" cy="10" r="6" />32 <circle cx="30" cy="10" r="6" />33 <circle cx="50" cy="10" r="6" />34 </svg>35</div>36<style>37 .sg-dots-pulse {38 width: var(--sg-size);39 }40 .sg-dots-pulse svg {41 display: block;42 width: 100%;43 }44 .sg-dots-pulse circle {45 fill: var(--sg-color);46 transform-box: fill-box;47 transform-origin: center;48 animation: sg-dots-pulse-beat var(--sg-duration) ease-in-out infinite;49 }50 .sg-dots-pulse circle:nth-of-type(2) { animation-delay: calc(var(--sg-duration) / 3); }51 .sg-dots-pulse circle:nth-of-type(3) { animation-delay: calc(var(--sg-duration) / 3 * 2); }52 @keyframes sg-dots-pulse-beat {53 0%, 100% { transform: scale(1); opacity: 1; }54 50% { transform: scale(0.45); opacity: 0.35; }55 }56</style>57