Pure CSS audio visualizer
A visually engaging, interactive audio visualizer built with only HTML and CSS, featuring animated bars triggered by a custom toggle button.
Overview
This component simulates a classic "audio bar" visualizer animation. Users can toggle between "play" and "pause" states with a stylish button. All bar movements and effects are powered by CSS keyframes and gradients—no JavaScript required.
Structure
HTML
- Container: .audio-visualizer is the main wrapper.
- Toggle: An invisible checkbox (#playToggle) and an associated label (.toggle-btn) allow users to control the play/pause state. The label acts as the visible button.
- Visualizer Bars: .bars contains seven .bar elements, each styled with a unique gradient.
<div class="audio-visualizer">
<input type="checkbox" id="playToggle" hidden>
<label for="playToggle" class="toggle-btn">▶️ Play / ⏸ Pause</label>
<div class="bars">
<div class="bar bar1"></div>
<div class="bar bar2"></div>
<div class="bar bar3"></div>
<div class="bar bar4"></div>
<div class="bar bar5"></div>
<div class="bar bar6"></div>
<div class="bar bar7"></div>
</div>
</div>
Toggle Button
- Styled Label: Large, pill-shaped button using a linear gradient background.
- Interactive Feedback: On hover, the gradient changes for a dynamic effect.
- UX: Displays "Play" and "Pause" icons and text for accessibility .
Bars Visualization
- Layout: Flexbox arranges bars horizontally, with spacing and vertical bottom alignment.
- Gradients: Each bar uses a different vertical gradient for a vibrant, multi-color effect.
- Bar Size: All bars start at 20px height by default.
body {
background:black;
}
.audio-visualizer {
width: 320px;
margin: 3rem auto;
font-family: system-ui, sans-serif;
text-align: center;
}
.toggle-btn {
cursor: pointer;
background: #3F5EFB;
background: linear-gradient(179deg,rgba(63, 94, 251, 1) 0%, rgba(252, 70, 107, 1) 100%);
color: white;
padding: 0.6rem 1.2rem;
border-radius: 25px;
font-weight: 600;
user-select: none;
margin-bottom: 1.5rem;
display: inline-block;
transition: background 0.3s;
}
.toggle-btn:hover {
background: #833AB4;
background: linear-gradient(180deg,rgba(131, 58, 180, 1) 0%, rgba(253, 29, 29, 1) 50%, rgba(252, 176, 69, 1) 100%);
}
.bars {
display: flex;
gap: 8px;
justify-content: center;
align-items: flex-end;
height: 160px;
}
.bar {
width: 18px;
border-radius: 3px;
animation: breath 2.5s ease-in-out infinite;
animation-play-state: paused;
height: 20px;
filter: none;
transition: filter 0.3s ease;
}
/* Each bar's unique gradient color */
.bar1 {
background: linear-gradient(180deg, #e63946, #a1202b);
animation-duration: 1.7s;
}
.bar2 {
background: linear-gradient(180deg, #f4a261, #a86d2b);
animation-duration: 2.0s;
}
.bar3 {
background: linear-gradient(180deg, #2a9d8f, #1d675d);
animation-duration: 1.3s;
}
.bar4 {
background: linear-gradient(180deg, #e76f51, #a0422a);
animation-duration: 1.6s;
}
.bar5 {
background: linear-gradient(180deg, #264653, #152733);
animation-duration: 1.9s;
}
.bar6 {
background: linear-gradient(180deg, #ffb703, #c78f00);
animation-duration: 2.2s;
}
.bar7 {
background: linear-gradient(180deg, #8ecae6, #5a8fbf);
animation-duration: 1.5s;
}
/* Breath animation for pause */
@keyframes breath {
0%, 100% { height: 20px; filter: none; }
50% { height: 30px; filter: none; }
}
/* Play state bars animation */
@keyframes audioWave {
0%, 100% { height: 20px; filter: none; }
25% { height: 100px; filter: blur(2px); }
50% { height: 60px; filter: blur(1.5px); }
75% { height: 110px; filter: blur(2.5px); }
}
/* When playToggle is checked, start audio wave animation */
#playToggle:checked ~ .bars .bar {
animation-name: audioWave;
animation-play-state: running;
}
/* Stagger the animation delays for wave effect */
#playToggle:checked ~ .bars .bar1 { animation-delay: 0s; }
#playToggle:checked ~ .bars .bar2 { animation-delay: 0.15s; }
#playToggle:checked ~ .bars .bar3 { animation-delay: 0.3s; }
#playToggle:checked ~ .bars .bar4 { animation-delay: 0.45s; }
#playToggle:checked ~ .bars .bar5 { animation-delay: 0.6s; }
#playToggle:checked ~ .bars .bar6 { animation-delay: 0.75s; }
#playToggle:checked ~ .bars .bar7 { animation-delay: 0.9s; }

Top comments (2)
Very nice
Some comments may only be visible to logged-in visitors. Sign in to view all comments.