That player bar pinned to the bottom of Spotify looks like a polished component. Build it and it's a 3-column grid + two divs + a timer. Day 6 of my DesignFromZero series.
Three columns
.sp-bar {
display: grid;
grid-template-columns: 1fr auto 1fr; /* track · controls · volume */
align-items: center;
}
Left and right stretch; the centre is fixed — so the play button stays dead-centre at any width.
The progress bar is two divs
<div class="track"><div class="fill" style="width: 42%"></div></div>
Outer = grey rail, inner width% = elapsed. Spotify's signature touch: the fill is white, turns green on hover, and a knob appears.
.track:hover .fill { background: #1db954; }
"Playing" = a boolean + a 1-second timer
You don't need real audio to sell it. Hold elapsed seconds, tick every second, grow the fill:
let t = 0, playing = false;
setInterval(() => { if (playing && t < DUR) { t++; render(); } }, 1000);
playBtn.onclick = () => playing = !playing;
Scrub with offsetX
track.onclick = e => { t = (e.offsetX / track.clientWidth) * DUR; };
offsetX is the click position inside the rail; divide by width for a 0–1 fraction. One line gives click-to-seek.
Swap the fake timer for a real <audio> element's currentTime and it's a genuine player — the structure doesn't change.
🎵 See it live (hit play, scrub the bar): https://dev48v.infy.uk/design/day6-spotify-nowplaying.html
Day 6 of DesignFromZero.
Top comments (0)