26 CSS Dividers23 / 26
Audio Waveform SVG Divider CSS
A waveform divider for podcast and music pages, built as flex bars rather than an SVG path — which means every bar is an element you can animate, colour and stagger independently. Heights come from a hand-tuned array so the shape reads as real audio (asymmetric, with quiet passages), and a played/unplayed split shows the progress-bar pattern the pattern is actually used for.
Published Updated
The code
<section class="div-23" aria-label="Audio waveform divider demo">
<div class="div-23__stage">
<div class="div-23__card">
<div class="div-23__row">
<span class="div-23__art" aria-hidden="true"></span>
<span class="div-23__meta"><b>Episode 26 — Dividing Lines</b><br>Codefronts Radio · 41 min</span>
</div>
<div class="div-23__wave" aria-hidden="true">
<span class="div-23__bar" style="--div-23-h:22%;--div-23-i:0"></span><span class="div-23__bar" style="--div-23-h:44%;--div-23-i:1"></span><span class="div-23__bar" style="--div-23-h:70%;--div-23-i:2"></span><span class="div-23__bar" style="--div-23-h:96%;--div-23-i:3"></span><span class="div-23__bar" style="--div-23-h:62%;--div-23-i:4"></span><span class="div-23__bar" style="--div-23-h:36%;--div-23-i:5"></span><span class="div-23__bar" style="--div-23-h:52%;--div-23-i:6"></span><span class="div-23__bar" style="--div-23-h:84%;--div-23-i:7"></span><span class="div-23__bar" style="--div-23-h:58%;--div-23-i:8"></span><span class="div-23__bar" style="--div-23-h:28%;--div-23-i:9"></span><span class="div-23__bar" style="--div-23-h:18%;--div-23-i:10"></span><span class="div-23__bar" style="--div-23-h:40%;--div-23-i:11"></span><span class="div-23__bar" style="--div-23-h:76%;--div-23-i:12"></span><span class="div-23__bar" style="--div-23-h:100%;--div-23-i:13"></span><span class="div-23__bar" style="--div-23-h:66%;--div-23-i:14"></span><span class="div-23__bar" style="--div-23-h:34%;--div-23-i:15"></span><span class="div-23__bar" style="--div-23-h:48%;--div-23-i:16"></span><span class="div-23__bar" style="--div-23-h:80%;--div-23-i:17"></span><span class="div-23__bar" style="--div-23-h:54%;--div-23-i:18"></span><span class="div-23__bar" style="--div-23-h:24%;--div-23-i:19"></span><span class="div-23__bar" style="--div-23-h:42%;--div-23-i:20"></span><span class="div-23__bar" style="--div-23-h:88%;--div-23-i:21"></span><span class="div-23__bar" style="--div-23-h:60%;--div-23-i:22"></span><span class="div-23__bar" style="--div-23-h:30%;--div-23-i:23"></span><span class="div-23__bar" style="--div-23-h:16%;--div-23-i:24"></span><span class="div-23__bar" style="--div-23-h:46%;--div-23-i:25"></span><span class="div-23__bar" style="--div-23-h:72%;--div-23-i:26"></span><span class="div-23__bar" style="--div-23-h:92%;--div-23-i:27"></span><span class="div-23__bar" style="--div-23-h:56%;--div-23-i:28"></span><span class="div-23__bar" style="--div-23-h:26%;--div-23-i:29"></span>
</div>
<div class="div-23__time"><span>17:42</span><span>41:03</span></div>
</div>
<p class="div-23__chip">--h per bar · calc(--i × -.07s) stagger · scaleY not height</p>
</div>
</section><section class="div-23" aria-label="Audio waveform divider demo">
<div class="div-23__stage">
<div class="div-23__card">
<div class="div-23__row">
<span class="div-23__art" aria-hidden="true"></span>
<span class="div-23__meta"><b>Episode 26 — Dividing Lines</b><br>Codefronts Radio · 41 min</span>
</div>
<div class="div-23__wave" aria-hidden="true">
<span class="div-23__bar" style="--div-23-h:22%;--div-23-i:0"></span><span class="div-23__bar" style="--div-23-h:44%;--div-23-i:1"></span><span class="div-23__bar" style="--div-23-h:70%;--div-23-i:2"></span><span class="div-23__bar" style="--div-23-h:96%;--div-23-i:3"></span><span class="div-23__bar" style="--div-23-h:62%;--div-23-i:4"></span><span class="div-23__bar" style="--div-23-h:36%;--div-23-i:5"></span><span class="div-23__bar" style="--div-23-h:52%;--div-23-i:6"></span><span class="div-23__bar" style="--div-23-h:84%;--div-23-i:7"></span><span class="div-23__bar" style="--div-23-h:58%;--div-23-i:8"></span><span class="div-23__bar" style="--div-23-h:28%;--div-23-i:9"></span><span class="div-23__bar" style="--div-23-h:18%;--div-23-i:10"></span><span class="div-23__bar" style="--div-23-h:40%;--div-23-i:11"></span><span class="div-23__bar" style="--div-23-h:76%;--div-23-i:12"></span><span class="div-23__bar" style="--div-23-h:100%;--div-23-i:13"></span><span class="div-23__bar" style="--div-23-h:66%;--div-23-i:14"></span><span class="div-23__bar" style="--div-23-h:34%;--div-23-i:15"></span><span class="div-23__bar" style="--div-23-h:48%;--div-23-i:16"></span><span class="div-23__bar" style="--div-23-h:80%;--div-23-i:17"></span><span class="div-23__bar" style="--div-23-h:54%;--div-23-i:18"></span><span class="div-23__bar" style="--div-23-h:24%;--div-23-i:19"></span><span class="div-23__bar" style="--div-23-h:42%;--div-23-i:20"></span><span class="div-23__bar" style="--div-23-h:88%;--div-23-i:21"></span><span class="div-23__bar" style="--div-23-h:60%;--div-23-i:22"></span><span class="div-23__bar" style="--div-23-h:30%;--div-23-i:23"></span><span class="div-23__bar" style="--div-23-h:16%;--div-23-i:24"></span><span class="div-23__bar" style="--div-23-h:46%;--div-23-i:25"></span><span class="div-23__bar" style="--div-23-h:72%;--div-23-i:26"></span><span class="div-23__bar" style="--div-23-h:92%;--div-23-i:27"></span><span class="div-23__bar" style="--div-23-h:56%;--div-23-i:28"></span><span class="div-23__bar" style="--div-23-h:26%;--div-23-i:29"></span>
</div>
<div class="div-23__time"><span>17:42</span><span>41:03</span></div>
</div>
<p class="div-23__chip">--h per bar · calc(--i × -.07s) stagger · scaleY not height</p>
</div>
</section>.div-23 {
width: 100%;
min-height: 100vh;
min-height: 100svh;
display: block;
background: var(--div-23-bg);
--div-23-bg: oklch(0.16 0.024 300);
--div-23-card: oklch(0.21 0.03 300);
--div-23-ink: oklch(0.95 0.01 300);
--div-23-mut: oklch(0.65 0.03 300);
--div-23-acc: oklch(0.55 0.09 300);
--div-23-hot: oklch(0.78 0.17 340);
font-family: 'Segoe UI',system-ui,-apple-system,sans-serif;
color: var(--div-23-ink);
}
.div-23 *,
.div-23 *::before,
.div-23 *::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.div-23__stage {
min-height: 100svh;
display: grid;
place-content: center;
justify-items: center;
gap: 20px;
padding: clamp(24px,5vw,60px) clamp(20px,5vw,56px);
background: radial-gradient(80% 60% at 50% 100%,oklch(0.3 0.09 330/.55),transparent);
}
.div-23__card {
width: min(94vw,640px);
background: var(--div-23-card);
border: 1px solid oklch(1 0 0/.09);
border-radius: 20px;
padding: clamp(20px,4vw,30px);
box-shadow: 0 26px 60px oklch(0 0 0/.45);
display: grid;
gap: 18px;
}
.div-23__row {
display: flex;
align-items: center;
gap: 14px;
}
.div-23__art {
width: 52px;
height: 52px;
flex: none;
border-radius: 12px;
background: linear-gradient(140deg,var(--div-23-hot),oklch(0.5 0.15 285)),url("https://images.unsplash.com/photo-1478737270239-2f02b77fc618?q=80&w=400&auto=format&fit=crop") center/cover no-repeat;
background-blend-mode: soft-light,normal;
}
.div-23__meta {
font-size: 13px;
line-height: 1.5;
color: var(--div-23-mut);
}
.div-23__meta b {
color: var(--div-23-ink);
font-size: 14.5px;
font-weight: 650;
}
.div-23__wave {
display: flex;
align-items: center;
gap: 3px;
height: clamp(54px,9vw,76px);
-webkit-mask: linear-gradient(90deg,#0000,#000 4%,#000 96%,#0000);
mask: linear-gradient(90deg,#0000,#000 4%,#000 96%,#0000);
}
.div-23__bar {
flex: 1 1 0;
height: var(--div-23-h);
min-height: 4px;
border-radius: 99px;
background: var(--div-23-acc);
transform-origin: 50% 50%;
animation: div-23-eq 1.5s ease-in-out infinite;
animation-delay: calc(var(--div-23-i) * -.07s);
}
.div-23__bar:nth-child(-n+13) {
background: var(--div-23-hot);
box-shadow: 0 0 12px oklch(0.78 0.17 340/.35);
}
@keyframes div-23-eq {
0%,
100% {
scale: 1 .82;
}
50% {
scale: 1 1.14;
}
}
.div-23__time {
display: flex;
justify-content: space-between;
font-family: ui-monospace,Menlo,Consolas,monospace;
font-size: 11.5px;
color: var(--div-23-mut);
font-variant-numeric: tabular-nums;
}
.div-23__chip {
font-family: ui-monospace,Menlo,Consolas,monospace;
font-size: 11px;
color: var(--div-23-mut);
padding: 8px 14px;
border: 1px solid oklch(1 0 0/.14);
border-radius: 99px;
text-align: center;
max-width: 94vw;
}
@media (prefers-reduced-motion: reduce) {
.div-23__bar {
animation: none;
scale: 1 1;
}
}.div-23 {
width: 100%;
min-height: 100vh;
min-height: 100svh;
display: block;
background: var(--div-23-bg);
--div-23-bg: oklch(0.16 0.024 300);
--div-23-card: oklch(0.21 0.03 300);
--div-23-ink: oklch(0.95 0.01 300);
--div-23-mut: oklch(0.65 0.03 300);
--div-23-acc: oklch(0.55 0.09 300);
--div-23-hot: oklch(0.78 0.17 340);
font-family: 'Segoe UI',system-ui,-apple-system,sans-serif;
color: var(--div-23-ink);
}
.div-23 *,
.div-23 *::before,
.div-23 *::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.div-23__stage {
min-height: 100svh;
display: grid;
place-content: center;
justify-items: center;
gap: 20px;
padding: clamp(24px,5vw,60px) clamp(20px,5vw,56px);
background: radial-gradient(80% 60% at 50% 100%,oklch(0.3 0.09 330/.55),transparent);
}
.div-23__card {
width: min(94vw,640px);
background: var(--div-23-card);
border: 1px solid oklch(1 0 0/.09);
border-radius: 20px;
padding: clamp(20px,4vw,30px);
box-shadow: 0 26px 60px oklch(0 0 0/.45);
display: grid;
gap: 18px;
}
.div-23__row {
display: flex;
align-items: center;
gap: 14px;
}
.div-23__art {
width: 52px;
height: 52px;
flex: none;
border-radius: 12px;
background: linear-gradient(140deg,var(--div-23-hot),oklch(0.5 0.15 285)),url("https://images.unsplash.com/photo-1478737270239-2f02b77fc618?q=80&w=400&auto=format&fit=crop") center/cover no-repeat;
background-blend-mode: soft-light,normal;
}
.div-23__meta {
font-size: 13px;
line-height: 1.5;
color: var(--div-23-mut);
}
.div-23__meta b {
color: var(--div-23-ink);
font-size: 14.5px;
font-weight: 650;
}
.div-23__wave {
display: flex;
align-items: center;
gap: 3px;
height: clamp(54px,9vw,76px);
-webkit-mask: linear-gradient(90deg,#0000,#000 4%,#000 96%,#0000);
mask: linear-gradient(90deg,#0000,#000 4%,#000 96%,#0000);
}
.div-23__bar {
flex: 1 1 0;
height: var(--div-23-h);
min-height: 4px;
border-radius: 99px;
background: var(--div-23-acc);
transform-origin: 50% 50%;
animation: div-23-eq 1.5s ease-in-out infinite;
animation-delay: calc(var(--div-23-i) * -.07s);
}
.div-23__bar:nth-child(-n+13) {
background: var(--div-23-hot);
box-shadow: 0 0 12px oklch(0.78 0.17 340/.35);
}
@keyframes div-23-eq {
0%,
100% {
scale: 1 .82;
}
50% {
scale: 1 1.14;
}
}
.div-23__time {
display: flex;
justify-content: space-between;
font-family: ui-monospace,Menlo,Consolas,monospace;
font-size: 11.5px;
color: var(--div-23-mut);
font-variant-numeric: tabular-nums;
}
.div-23__chip {
font-family: ui-monospace,Menlo,Consolas,monospace;
font-size: 11px;
color: var(--div-23-mut);
padding: 8px 14px;
border: 1px solid oklch(1 0 0/.14);
border-radius: 99px;
text-align: center;
max-width: 94vw;
}
@media (prefers-reduced-motion: reduce) {
.div-23__bar {
animation: none;
scale: 1 1;
}
}Here's a working CSS Divider from CodeFronts. Use it as-is or adapt to your framework. All classes are scoped under a unique prefix so the code won't collide with your existing styles. MIT licensed.
Demo: Audio Waveform SVG Divider CSS
Source: https://codefronts.com/snippets/css-dividers/music-dividers/
A waveform divider for podcast and music pages, built as flex bars rather than an SVG path — which means every bar is an element you can animate, colour and stagger independently. Heights come from a hand-tuned array so the shape reads as real audio (asymmetric, with quiet passages), and a played/unplayed split shows the progress-bar pattern the pattern is actually used for.
## HTML
```html
<section class="div-23" aria-label="Audio waveform divider demo">
<div class="div-23__stage">
<div class="div-23__card">
<div class="div-23__row">
<span class="div-23__art" aria-hidden="true"></span>
<span class="div-23__meta"><b>Episode 26 — Dividing Lines</b><br>Codefronts Radio · 41 min</span>
</div>
<div class="div-23__wave" aria-hidden="true">
<span class="div-23__bar" style="--div-23-h:22%;--div-23-i:0"></span><span class="div-23__bar" style="--div-23-h:44%;--div-23-i:1"></span><span class="div-23__bar" style="--div-23-h:70%;--div-23-i:2"></span><span class="div-23__bar" style="--div-23-h:96%;--div-23-i:3"></span><span class="div-23__bar" style="--div-23-h:62%;--div-23-i:4"></span><span class="div-23__bar" style="--div-23-h:36%;--div-23-i:5"></span><span class="div-23__bar" style="--div-23-h:52%;--div-23-i:6"></span><span class="div-23__bar" style="--div-23-h:84%;--div-23-i:7"></span><span class="div-23__bar" style="--div-23-h:58%;--div-23-i:8"></span><span class="div-23__bar" style="--div-23-h:28%;--div-23-i:9"></span><span class="div-23__bar" style="--div-23-h:18%;--div-23-i:10"></span><span class="div-23__bar" style="--div-23-h:40%;--div-23-i:11"></span><span class="div-23__bar" style="--div-23-h:76%;--div-23-i:12"></span><span class="div-23__bar" style="--div-23-h:100%;--div-23-i:13"></span><span class="div-23__bar" style="--div-23-h:66%;--div-23-i:14"></span><span class="div-23__bar" style="--div-23-h:34%;--div-23-i:15"></span><span class="div-23__bar" style="--div-23-h:48%;--div-23-i:16"></span><span class="div-23__bar" style="--div-23-h:80%;--div-23-i:17"></span><span class="div-23__bar" style="--div-23-h:54%;--div-23-i:18"></span><span class="div-23__bar" style="--div-23-h:24%;--div-23-i:19"></span><span class="div-23__bar" style="--div-23-h:42%;--div-23-i:20"></span><span class="div-23__bar" style="--div-23-h:88%;--div-23-i:21"></span><span class="div-23__bar" style="--div-23-h:60%;--div-23-i:22"></span><span class="div-23__bar" style="--div-23-h:30%;--div-23-i:23"></span><span class="div-23__bar" style="--div-23-h:16%;--div-23-i:24"></span><span class="div-23__bar" style="--div-23-h:46%;--div-23-i:25"></span><span class="div-23__bar" style="--div-23-h:72%;--div-23-i:26"></span><span class="div-23__bar" style="--div-23-h:92%;--div-23-i:27"></span><span class="div-23__bar" style="--div-23-h:56%;--div-23-i:28"></span><span class="div-23__bar" style="--div-23-h:26%;--div-23-i:29"></span>
</div>
<div class="div-23__time"><span>17:42</span><span>41:03</span></div>
</div>
<p class="div-23__chip">--h per bar · calc(--i × -.07s) stagger · scaleY not height</p>
</div>
</section>
```
## CSS
```css
.div-23 {
width: 100%;
min-height: 100vh;
min-height: 100svh;
display: block;
background: var(--div-23-bg);
--div-23-bg: oklch(0.16 0.024 300);
--div-23-card: oklch(0.21 0.03 300);
--div-23-ink: oklch(0.95 0.01 300);
--div-23-mut: oklch(0.65 0.03 300);
--div-23-acc: oklch(0.55 0.09 300);
--div-23-hot: oklch(0.78 0.17 340);
font-family: 'Segoe UI',system-ui,-apple-system,sans-serif;
color: var(--div-23-ink);
}
.div-23 *,
.div-23 *::before,
.div-23 *::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.div-23__stage {
min-height: 100svh;
display: grid;
place-content: center;
justify-items: center;
gap: 20px;
padding: clamp(24px,5vw,60px) clamp(20px,5vw,56px);
background: radial-gradient(80% 60% at 50% 100%,oklch(0.3 0.09 330/.55),transparent);
}
.div-23__card {
width: min(94vw,640px);
background: var(--div-23-card);
border: 1px solid oklch(1 0 0/.09);
border-radius: 20px;
padding: clamp(20px,4vw,30px);
box-shadow: 0 26px 60px oklch(0 0 0/.45);
display: grid;
gap: 18px;
}
.div-23__row {
display: flex;
align-items: center;
gap: 14px;
}
.div-23__art {
width: 52px;
height: 52px;
flex: none;
border-radius: 12px;
background: linear-gradient(140deg,var(--div-23-hot),oklch(0.5 0.15 285)),url("https://images.unsplash.com/photo-1478737270239-2f02b77fc618?q=80&w=400&auto=format&fit=crop") center/cover no-repeat;
background-blend-mode: soft-light,normal;
}
.div-23__meta {
font-size: 13px;
line-height: 1.5;
color: var(--div-23-mut);
}
.div-23__meta b {
color: var(--div-23-ink);
font-size: 14.5px;
font-weight: 650;
}
.div-23__wave {
display: flex;
align-items: center;
gap: 3px;
height: clamp(54px,9vw,76px);
-webkit-mask: linear-gradient(90deg,#0000,#000 4%,#000 96%,#0000);
mask: linear-gradient(90deg,#0000,#000 4%,#000 96%,#0000);
}
.div-23__bar {
flex: 1 1 0;
height: var(--div-23-h);
min-height: 4px;
border-radius: 99px;
background: var(--div-23-acc);
transform-origin: 50% 50%;
animation: div-23-eq 1.5s ease-in-out infinite;
animation-delay: calc(var(--div-23-i) * -.07s);
}
.div-23__bar:nth-child(-n+13) {
background: var(--div-23-hot);
box-shadow: 0 0 12px oklch(0.78 0.17 340/.35);
}
@keyframes div-23-eq {
0%,
100% {
scale: 1 .82;
}
50% {
scale: 1 1.14;
}
}
.div-23__time {
display: flex;
justify-content: space-between;
font-family: ui-monospace,Menlo,Consolas,monospace;
font-size: 11.5px;
color: var(--div-23-mut);
font-variant-numeric: tabular-nums;
}
.div-23__chip {
font-family: ui-monospace,Menlo,Consolas,monospace;
font-size: 11px;
color: var(--div-23-mut);
padding: 8px 14px;
border: 1px solid oklch(1 0 0/.14);
border-radius: 99px;
text-align: center;
max-width: 94vw;
}
@media (prefers-reduced-motion: reduce) {
.div-23__bar {
animation: none;
scale: 1 1;
}
}
```Here's a working CSS Divider from CodeFronts. Use it as-is or adapt to your framework. All classes are scoped under a unique prefix so the code won't collide with your existing styles. MIT licensed.
Demo: Audio Waveform SVG Divider CSS
Source: https://codefronts.com/snippets/css-dividers/music-dividers/
A waveform divider for podcast and music pages, built as flex bars rather than an SVG path — which means every bar is an element you can animate, colour and stagger independently. Heights come from a hand-tuned array so the shape reads as real audio (asymmetric, with quiet passages), and a played/unplayed split shows the progress-bar pattern the pattern is actually used for.
## HTML
```html
<section class="div-23" aria-label="Audio waveform divider demo">
<div class="div-23__stage">
<div class="div-23__card">
<div class="div-23__row">
<span class="div-23__art" aria-hidden="true"></span>
<span class="div-23__meta"><b>Episode 26 — Dividing Lines</b><br>Codefronts Radio · 41 min</span>
</div>
<div class="div-23__wave" aria-hidden="true">
<span class="div-23__bar" style="--div-23-h:22%;--div-23-i:0"></span><span class="div-23__bar" style="--div-23-h:44%;--div-23-i:1"></span><span class="div-23__bar" style="--div-23-h:70%;--div-23-i:2"></span><span class="div-23__bar" style="--div-23-h:96%;--div-23-i:3"></span><span class="div-23__bar" style="--div-23-h:62%;--div-23-i:4"></span><span class="div-23__bar" style="--div-23-h:36%;--div-23-i:5"></span><span class="div-23__bar" style="--div-23-h:52%;--div-23-i:6"></span><span class="div-23__bar" style="--div-23-h:84%;--div-23-i:7"></span><span class="div-23__bar" style="--div-23-h:58%;--div-23-i:8"></span><span class="div-23__bar" style="--div-23-h:28%;--div-23-i:9"></span><span class="div-23__bar" style="--div-23-h:18%;--div-23-i:10"></span><span class="div-23__bar" style="--div-23-h:40%;--div-23-i:11"></span><span class="div-23__bar" style="--div-23-h:76%;--div-23-i:12"></span><span class="div-23__bar" style="--div-23-h:100%;--div-23-i:13"></span><span class="div-23__bar" style="--div-23-h:66%;--div-23-i:14"></span><span class="div-23__bar" style="--div-23-h:34%;--div-23-i:15"></span><span class="div-23__bar" style="--div-23-h:48%;--div-23-i:16"></span><span class="div-23__bar" style="--div-23-h:80%;--div-23-i:17"></span><span class="div-23__bar" style="--div-23-h:54%;--div-23-i:18"></span><span class="div-23__bar" style="--div-23-h:24%;--div-23-i:19"></span><span class="div-23__bar" style="--div-23-h:42%;--div-23-i:20"></span><span class="div-23__bar" style="--div-23-h:88%;--div-23-i:21"></span><span class="div-23__bar" style="--div-23-h:60%;--div-23-i:22"></span><span class="div-23__bar" style="--div-23-h:30%;--div-23-i:23"></span><span class="div-23__bar" style="--div-23-h:16%;--div-23-i:24"></span><span class="div-23__bar" style="--div-23-h:46%;--div-23-i:25"></span><span class="div-23__bar" style="--div-23-h:72%;--div-23-i:26"></span><span class="div-23__bar" style="--div-23-h:92%;--div-23-i:27"></span><span class="div-23__bar" style="--div-23-h:56%;--div-23-i:28"></span><span class="div-23__bar" style="--div-23-h:26%;--div-23-i:29"></span>
</div>
<div class="div-23__time"><span>17:42</span><span>41:03</span></div>
</div>
<p class="div-23__chip">--h per bar · calc(--i × -.07s) stagger · scaleY not height</p>
</div>
</section>
```
## CSS
```css
.div-23 {
width: 100%;
min-height: 100vh;
min-height: 100svh;
display: block;
background: var(--div-23-bg);
--div-23-bg: oklch(0.16 0.024 300);
--div-23-card: oklch(0.21 0.03 300);
--div-23-ink: oklch(0.95 0.01 300);
--div-23-mut: oklch(0.65 0.03 300);
--div-23-acc: oklch(0.55 0.09 300);
--div-23-hot: oklch(0.78 0.17 340);
font-family: 'Segoe UI',system-ui,-apple-system,sans-serif;
color: var(--div-23-ink);
}
.div-23 *,
.div-23 *::before,
.div-23 *::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.div-23__stage {
min-height: 100svh;
display: grid;
place-content: center;
justify-items: center;
gap: 20px;
padding: clamp(24px,5vw,60px) clamp(20px,5vw,56px);
background: radial-gradient(80% 60% at 50% 100%,oklch(0.3 0.09 330/.55),transparent);
}
.div-23__card {
width: min(94vw,640px);
background: var(--div-23-card);
border: 1px solid oklch(1 0 0/.09);
border-radius: 20px;
padding: clamp(20px,4vw,30px);
box-shadow: 0 26px 60px oklch(0 0 0/.45);
display: grid;
gap: 18px;
}
.div-23__row {
display: flex;
align-items: center;
gap: 14px;
}
.div-23__art {
width: 52px;
height: 52px;
flex: none;
border-radius: 12px;
background: linear-gradient(140deg,var(--div-23-hot),oklch(0.5 0.15 285)),url("https://images.unsplash.com/photo-1478737270239-2f02b77fc618?q=80&w=400&auto=format&fit=crop") center/cover no-repeat;
background-blend-mode: soft-light,normal;
}
.div-23__meta {
font-size: 13px;
line-height: 1.5;
color: var(--div-23-mut);
}
.div-23__meta b {
color: var(--div-23-ink);
font-size: 14.5px;
font-weight: 650;
}
.div-23__wave {
display: flex;
align-items: center;
gap: 3px;
height: clamp(54px,9vw,76px);
-webkit-mask: linear-gradient(90deg,#0000,#000 4%,#000 96%,#0000);
mask: linear-gradient(90deg,#0000,#000 4%,#000 96%,#0000);
}
.div-23__bar {
flex: 1 1 0;
height: var(--div-23-h);
min-height: 4px;
border-radius: 99px;
background: var(--div-23-acc);
transform-origin: 50% 50%;
animation: div-23-eq 1.5s ease-in-out infinite;
animation-delay: calc(var(--div-23-i) * -.07s);
}
.div-23__bar:nth-child(-n+13) {
background: var(--div-23-hot);
box-shadow: 0 0 12px oklch(0.78 0.17 340/.35);
}
@keyframes div-23-eq {
0%,
100% {
scale: 1 .82;
}
50% {
scale: 1 1.14;
}
}
.div-23__time {
display: flex;
justify-content: space-between;
font-family: ui-monospace,Menlo,Consolas,monospace;
font-size: 11.5px;
color: var(--div-23-mut);
font-variant-numeric: tabular-nums;
}
.div-23__chip {
font-family: ui-monospace,Menlo,Consolas,monospace;
font-size: 11px;
color: var(--div-23-mut);
padding: 8px 14px;
border: 1px solid oklch(1 0 0/.14);
border-radius: 99px;
text-align: center;
max-width: 94vw;
}
@media (prefers-reduced-motion: reduce) {
.div-23__bar {
animation: none;
scale: 1 1;
}
}
```How this works
Waveform bars are a flex row with per-bar heights and per-bar delays:
.wave{ display:flex; align-items:center; gap:3px; height:64px }
.bar { flex:1; border-radius:99px; background:var(--acc);
height:var(--h); /* set per bar in the markup */
transform-origin:50% 50%;
animation:eq 1.4s ease-in-out infinite;
animation-delay:calc(var(--i) * -.07s); }Two custom properties per bar — --h for its resting height and --i for its index — give you an arbitrary shape and a smooth travelling stagger from one calc(). Scaling with scaleY from a centred origin keeps the bars symmetric around the axis, which is what real audio looks like; scaling from the bottom makes it an equaliser instead. Both are valid, and the choice tells the viewer which one you meant.
The played/unplayed split is a second layer clipped by width:
.played{ position:absolute; inset:0; width:42%; overflow:hidden;
color:var(--hot) }Duplicating the bars inside a width-clipped overlay is far cheaper than recolouring individual bars, and it lets the boundary land mid-bar — exactly like every audio editor.
Real amplitude data is just an array of numbers written into --h; the same markup accepts output from the Web Audio API with no CSS change.
Make it yours
- Symmetric vs equaliser:
transform-origin:50% 50%for a waveform,50% 100%for VU-meter bars growing from a baseline. - Bar shape:
gap:1pxwith square ends reads as a spectrogram;gap:5pxwith a 99px radius reads as a modern player. - Real data: write
style="--h:38%"from your peak array. 60–120 bars is the readable range for a full-width divider. - Frozen waveform: drop the animation entirely — a static, well-shaped waveform is often the better divider, with motion reserved for the currently-playing track.
Gotchas — read before shipping
- Animating
heighton 40 bars forces 40 layouts per frame. AnimatescaleYand keep height static. - Uniform random heights look like noise, not audio. Real waveforms have quiet passages and clustered peaks — vary the envelope, not just each bar.
- A decorative waveform must be aria-hidden. If it is a progress control, it needs a real slider role, keyboard support and a text alternative for position.
- Very thin bars (under 2px) vanish at fractional zoom on low-DPI screens; 3px is the practical minimum.
Browser support
| Chrome | Safari | Firefox | Edge |
|---|---|---|---|
| 111+ | 16.4+ | 113+ | 111+ |
Flexbox, custom properties in calc() and scaleY animation work in every modern browser (Chrome 49, Safari 10, Firefox 31). Only oklch() sets the floor.