SPB Git

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%
2.1 KB · 57 lines html
Raw Blame History
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