audio-visualizer

Canvas-based audio visualization that pairs with any <audio> element via the for attribute. Supports bars, waveform, and circle modes.

Overview

A companion component that draws canvas-based audio visualizations. It connects to any <audio> element by ID via the for attribute — mirroring the <label for=""> pattern.

Separated from <audio-player> so it can be independently positioned, omitted, or paired with a plain <audio> element.

Visualization Modes

Bars (default)

Classic frequency bar chart equalizer. Press play to see the visualization.

<audio-player> <audio id="demo-track" controls> <source src="track.mp3" type="audio/mpeg"> <p><a href="track.mp3" download>Download track</a></p> </audio> </audio-player> <audio-visualizer for="demo-track" data-mode="bars"></audio-visualizer>

Waveform

Time-domain oscilloscope line.

<audio-player> <audio id="wave-track" controls> <source src="track.mp3" type="audio/mpeg"> <p><a href="track.mp3" download>Download track</a></p> </audio> </audio-player> <audio-visualizer for="wave-track" data-mode="waveform"></audio-visualizer>

Circle

Radial frequency display.

<audio-player> <audio id="circle-track" controls> <source src="track.mp3" type="audio/mpeg"> <p><a href="track.mp3" download>Download track</a></p> </audio> </audio-player> <audio-visualizer for="circle-track" data-mode="circle"></audio-visualizer>

Paired with audio-player

The visualizer works alongside <audio-player> — just give the inner <audio> an ID.

<audio-player> <audio id="my-track" controls> <source src="track.mp3" type="audio/mpeg"> <p><a href="track.mp3" download>Download</a></p> </audio> </audio-player> <audio-visualizer for="my-track" data-mode="bars"></audio-visualizer>

Attributes

AttributeRequiredDefaultDescription
forYes--ID of the target <audio> element
data-modeNobarsVisualization style: bars, waveform, circle
data-fft-sizeNo256AnalyserNode FFT size (power of 2, 32-32768)

CSS Custom Properties

PropertyDefaultDescription
--audio-visualizer-colorvar(--color-primary)Bar / waveform draw color
--audio-visualizer-bgvar(--color-surface-sunken)Canvas background
--audio-visualizer-height80pxCanvas block size
--audio-visualizer-radiusvar(--radius-m)Canvas border radius
audio-visualizer { --audio-visualizer-color: oklch(70% 0.25 145); --audio-visualizer-bg: oklch(10% 0.02 260); --audio-visualizer-height: 120px; --audio-visualizer-radius: var(--radius-l); }

Behavior

  • Lazy AudioContext — created on first play event, respects browser autoplay policy
  • Shared AudioContext — multiple visualizers on one page share a single context (browsers cap at ~6)
  • Off-screen pause — stops canvas rendering via IntersectionObserver when not visible
  • Reduced motion — stops canvas animation when prefers-reduced-motion: reduce is set; audio continues playing
  • Graceful fallback — if AudioContext is unavailable, renders nothing and throws no errors

Progressive Enhancement

Without JS, the visualizer renders nothing — the <audio> plays normally. The visualizer is pure enhancement with no impact on audio functionality.

The :not(:defined) CSS rule hides the element before JS loads, preventing a flash of unstyled content.

Accessibility

  • Canvas is aria-hidden="true" — purely decorative
  • Respects prefers-reduced-motion
  • Does not interfere with audio element controls or keyboard navigation

Related