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/gauges/battery-fill.html7 Desc : Battery icon charging up to a target level8 ============================================================9-->10<!--svgarden11title: Battery fill12slug: battery-fill13category: gauges14tags: [gauge, battery, charging, scaleX]15difficulty: intermediate16techniques: [scaleX, calc-with-custom-properties, transform-origin-left, "@keyframes"]17how_it_works: >18 The charge bar is a full-width rect scaled down horizontally: its resting19 state is scaleX(calc(var(--sg-level) / 100)), so the CSS variable directly is20 the battery percentage. The charging loop animates from scaleX(0) up to that21 same calculated value — because both the keyframe and the resting state read22 one variable, changing --sg-level retargets everything at once.23 transform-origin: left keeps the bar growing from the terminal end.24customizable:25 - { var: "--sg-color", label: "Charge color", type: color, default: "#2BA05A" }26 - { var: "--sg-size", label: "Size", type: range, min: 60, max: 240, default: 110, unit: px }27 - { var: "--sg-level", label: "Level %", type: range, min: 5, max: 100, default: 80 }28created: 2026-08-1029-->30<div class="sg-battery-fill" style="--sg-color:#2BA05A; --sg-size:110px; --sg-level:80;">31 <svg viewBox="0 0 56 28" role="img" aria-label="Battery charging">32 <title>Battery charging</title>33 <rect class="sg-battery-fill-case" x="2" y="4" width="46" height="20" rx="4" />34 <rect class="sg-battery-fill-cap" x="50" y="10" width="4" height="8" rx="1.5" />35 <rect class="sg-battery-fill-charge" x="5" y="7" width="40" height="14" rx="2" />36 </svg>37</div>38<style>39 .sg-battery-fill {40 width: var(--sg-size);41 }42 .sg-battery-fill svg {43 display: block;44 width: 100%;45 }46 .sg-battery-fill-case {47 fill: none;48 stroke: var(--sg-color);49 stroke-width: 2.5;50 opacity: 0.7;51 }52 .sg-battery-fill-cap {53 fill: var(--sg-color);54 opacity: 0.7;55 }56 .sg-battery-fill-charge {57 fill: var(--sg-color);58 transform-box: fill-box;59 transform-origin: left center;60 transform: scaleX(calc(var(--sg-level) / 100));61 animation: sg-battery-fill-charge-up 2.4s ease-out infinite;62 }63 @keyframes sg-battery-fill-charge-up {64 0% { transform: scaleX(0); opacity: 0.6; }65 75%, 88% { transform: scaleX(calc(var(--sg-level) / 100)); opacity: 1; }66 100% { transform: scaleX(calc(var(--sg-level) / 100)); opacity: 0.6; }67 }68</style>69