webdevpuneet.com

Battery Indicator — Free CSS Battery Level HTML JS Snippet

Battery Indicator · Dashboards · Plain HTML, CSS & JS · Live preview

CategoryDashboards

Copy & paste

Source Code

<div class="bat-card">
  <div class="bat-shell" id="batShell">
    <div class="bat-body">
      <div class="bat-fill" id="batFill"></div>
      <div class="bat-bolt" id="batBolt">
        <svg viewBox="0 0 24 24" fill="currentColor"><path d="M13 2 4 14h6l-1 8 9-12h-6z"></path></svg>
      </div>
      <span class="bat-pct" id="batPct">72%</span>
    </div>
    <div class="bat-cap"></div>
  </div>
  <label class="bat-slider">Level
    <input type="range" id="batRange" min="0" max="100" value="72">
  </label>
  <button type="button" class="bat-charge" id="batCharge">Toggle charging</button>
</div>

Extend with AI

Take This Snippet Further With AI

The AI prompt for this one is for Patreon supporters ($3 a month, 7 days free), along with a site with no ads. Supporters enter the passcode once and it is remembered in this browser.

· Become a supporter

What's included

Features

Pure CSS battery
Bordered body plus a cap nub — no images or icon font.
Percentage fill
Charge maps directly to the fill div's width value.
Color thresholds
Green, amber, and red states toggled in one paint() function.
Smooth transitions
Width and color animate with a cubic-bezier ease.
Charging mode
Bolt icon, pulsing fill, and a slow creep toward 100%.
No timer leaks
The charging interval is cleared the moment it stops.
Readable label
Centered percentage with a shadow over any fill color.
No dependency
Pure HTML/CSS/JS, ready to drop into any status bar.

About this UI Snippet

Battery Indicator — Animated Charge Level Widget

Screenshot of the Battery Indicator snippet rendered live

A battery indicator shows a device's charge as a familiar battery icon that fills and changes color — the control you see in status bars, IoT dashboards, EV apps, and laptop settings. This snippet builds one entirely from HTML, CSS, and vanilla JavaScript: a battery shell with a cap, a fill bar that animates between levels, color thresholds, and a charging mode with an animated bolt that slowly tops the battery up. No images, no SVG sprite sheet, no dependency.

The battery shape in pure CSS

The casing is a bordered rounded rectangle (.bat-body) with a small separate nub (.bat-cap) sitting against its right edge — together they read instantly as a battery. The fill is an absolutely-positioned inner div whose width is a percentage, so the charge level maps directly to a single CSS value. overflow:hidden on the body clips the fill to the rounded corners cleanly.

Color thresholds

Charge level drives three states via class toggles: at or below 12% the shell gets .crit (red), between 13–30% it gets .low (amber), and above that it stays green. The thresholds live in one paint() function with classList.toggle(name, condition), so the color logic is declarative — change the numbers in one place and both the bar and any themed elements follow.

Smooth level transitions

The fill's width and background are transitioned with a cubic-bezier ease, so dragging the slider or stepping the level animates fluidly rather than jumping. The percentage label is centered over the bar with a text shadow so it stays readable against both the dark empty track and the bright fill.

Charging mode

Toggling charge adds a .charging class that fades in a lightning-bolt SVG (hiding the percentage), runs a gentle batPulse opacity keyframe on the fill, and starts a setInterval that increments the level by 1% every 420ms until it reaches 100% — a believable "topping up" animation. Stopping charging clears the interval immediately so no timer leaks.

Wiring to real power data

Replace the slider with a real source: the browser navigator.getBattery() API exposes level and charging, or you can feed values from a device over WebSocket. Call paint() whenever the value changes; because all rendering is centralized there, the indicator stays a thin, stateless view over whatever charge number you give it.

Step by step

How to Use

  1. 1
    Paste HTML, CSS, and JSA battery shell renders with a fill bar and a percentage label.
  2. 2
    Drag the level sliderThe fill width animates and the percentage updates as you move it.
  3. 3
    Watch the color changeBelow 30% the fill turns amber, below 12% it turns red.
  4. 4
    Toggle chargingA lightning bolt appears and the bar pulses while the level creeps up.
  5. 5
    Let it reach fullCharging stops cleanly at 100% and the interval is cleared.
  6. 6
    Feed real dataReplace the slider with navigator.getBattery() and call paint().

Real-world uses

Common Use Cases

Device status panels
Show charge beside a signal bars meter, with the fill turning green, amber or red as the level crosses each threshold.
IoT and hardware dashboards
Render the live battery level reported by a sensor, using a bordered body and a cap nub built from CSS alone, with no icon font.
EV and energy apps
Visualise state of charge next to a radial bar chart of range, with a pulsing charging bolt showing power is flowing.
Quota and allowance views
Reuse the fill pattern for a quota usage meter, where width maps directly to a percentage with a smooth cubic-bezier ease.
Fleet health overviews
Pair with a status pill to flag devices needing attention, and a gauge chart for the fleet-wide average.
Related: Canvas Gravity Particle Orbits
See the Canvas Gravity Particle Orbits for a related animations pattern worth pairing with this one.
Related: Filter Icon Active-State Morph
See the Filter Icon Active-State Morph for a related animations pattern worth pairing with this one.

Got questions?

Frequently Asked Questions

The body is a div with a thick border and rounded corners, and the terminal is a separate small div (the cap) placed against its right edge. The colored fill is an inner div with a percentage width, and overflow:hidden on the body clips it to the rounded corners. The whole icon is three divs and no graphics.

The paint() function calls classList.toggle('crit', level <= 12) and classList.toggle('low', level > 12 && level <= 30). Those classes change the fill background to red or amber; above 30% neither class applies and it stays green. Adjusting the breakpoints is a one-line change.

A .charging class fades in a bolt SVG, hides the percentage, and runs a pulsing opacity animation on the fill. A setInterval then raises the level by 1% every 420ms until 100%, simulating a real charge. Toggling charging off clears the interval immediately, so there are no leftover timers.

Yes. The browser navigator.getBattery() API returns a promise with level (0–1) and charging fields plus change events. Multiply level by 100, set the slider or call paint() directly, and toggle the charging class from the API's charging value. Any live source — WebSocket, polling — works the same way.

Keep the level and charging flag in state and bind the fill width to a style with the percentage. Move the creep-up setInterval into an effect (useEffect, onMounted, or ngOnInit) and clear it on cleanup to avoid leaks. In Tailwind, set the fill width with an inline style and switch the green/amber/red background via conditional classes.