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/charts/chart-bar-race.html7 Desc : Horizontal bars racing to their values with spring stagger8 ============================================================9-->10<!--svgarden11title: Bar race12slug: chart-bar-race13category: charts14tags: [chart, bars, stagger, spring]15difficulty: intermediate16techniques: ["--sg-i index variables", "scaleX", "cubic-bezier() overshoot", "animation-delay"]17how_it_works: >18 Each bar is drawn at its final width in the markup — the data mapping is plain19 linear scaling, width = value × 1.6 units — and then compressed to zero with20 transform: scaleX(0), so the animation never has to know the value. The race21 feel comes from two ingredients: every row carries its rank in a --sg-i custom22 property, and one shared rule computes animation-delay: calc(var(--sg-i) × 18%23 of the duration), so adding a sixth bar means adding one line of markup, not24 one line of CSS. The overshoot is a cubic-bezier whose second control point25 rises above 1, making each bar shoot slightly past its value and settle back26 like a spring. Value labels reuse the same delay math plus most of the grow27 time, so each number pops in just as its bar arrives.28customizable:29 - { var: "--sg-color", label: "Bar color", type: color, default: "#7F77DD" }30 - { var: "--sg-size", label: "Width", type: range, min: 160, max: 420, default: 260, unit: px }31 - { var: "--sg-duration", label: "Speed", type: range, min: 0.4, max: 2.5, step: 0.1, default: 0.9, unit: s }32created: 2026-08-1033-->34<div class="sg-chart-bar-race" style="--sg-color:#7F77DD; --sg-size:260px; --sg-duration:0.9s;">35 <svg viewBox="0 0 240 118" role="img" aria-label="Bar chart: Python 92, Rust 78, Go 64, TypeScript 55, C 38">36 <title>Language popularity bar chart</title>37 <g class="sg-chart-bar-race-row" style="--sg-i:0">38 <text class="sg-chart-bar-race-name" x="48" y="20">Python</text>39 <rect class="sg-chart-bar-race-bar" x="54" y="10" width="147" height="12" rx="3" />40 <text class="sg-chart-bar-race-val" x="206" y="20">92</text>41 </g>42 <g class="sg-chart-bar-race-row" style="--sg-i:1">43 <text class="sg-chart-bar-race-name" x="48" y="42">Rust</text>44 <rect class="sg-chart-bar-race-bar" x="54" y="32" width="125" height="12" rx="3" />45 <text class="sg-chart-bar-race-val" x="184" y="42">78</text>46 </g>47 <g class="sg-chart-bar-race-row" style="--sg-i:2">48 <text class="sg-chart-bar-race-name" x="48" y="64">Go</text>49 <rect class="sg-chart-bar-race-bar" x="54" y="54" width="102" height="12" rx="3" />50 <text class="sg-chart-bar-race-val" x="161" y="64">64</text>51 </g>52 <g class="sg-chart-bar-race-row" style="--sg-i:3">53 <text class="sg-chart-bar-race-name" x="48" y="86">TypeScript</text>54 <rect class="sg-chart-bar-race-bar" x="54" y="76" width="88" height="12" rx="3" />55 <text class="sg-chart-bar-race-val" x="147" y="86">55</text>56 </g>57 <g class="sg-chart-bar-race-row" style="--sg-i:4">58 <text class="sg-chart-bar-race-name" x="48" y="108">C</text>59 <rect class="sg-chart-bar-race-bar" x="54" y="98" width="61" height="12" rx="3" />60 <text class="sg-chart-bar-race-val" x="120" y="108">38</text>61 </g>62 </svg>63</div>64<style>65 .sg-chart-bar-race {66 width: var(--sg-size);67 }68 .sg-chart-bar-race svg {69 display: block;70 width: 100%;71 font-family: inherit;72 }73 .sg-chart-bar-race-name {74 font-size: 10px;75 text-anchor: end;76 fill: currentColor;77 opacity: 0.75;78 }79 .sg-chart-bar-race-bar {80 fill: var(--sg-color);81 transform-box: fill-box;82 transform-origin: left center;83 animation: sg-chart-bar-race-grow var(--sg-duration) cubic-bezier(0.3, 1.35, 0.5, 1) both;84 animation-delay: calc(var(--sg-i) * var(--sg-duration) * 0.18);85 }86 .sg-chart-bar-race-row:nth-of-type(2) .sg-chart-bar-race-bar { opacity: 0.85; }87 .sg-chart-bar-race-row:nth-of-type(3) .sg-chart-bar-race-bar { opacity: 0.7; }88 .sg-chart-bar-race-row:nth-of-type(4) .sg-chart-bar-race-bar { opacity: 0.55; }89 .sg-chart-bar-race-row:nth-of-type(5) .sg-chart-bar-race-bar { opacity: 0.4; }90 .sg-chart-bar-race-val {91 font-size: 10px;92 font-weight: 600;93 fill: currentColor;94 animation: sg-chart-bar-race-fade 0.3s ease both;95 animation-delay: calc(var(--sg-i) * var(--sg-duration) * 0.18 + var(--sg-duration) * 0.75);96 }97 @keyframes sg-chart-bar-race-grow {98 from { transform: scaleX(0); }99 to { transform: scaleX(1); }100 }101 @keyframes sg-chart-bar-race-fade {102 from { opacity: 0; }103 to { opacity: 1; }104 }105</style>106