In short
Spotify's web player is a perfect app-shell layout: sidebar, main area that scrolls, and a player bar that never moves. Nail this and most dashboards will feel easy.
A recreation of Spotify's web player layout — sidebar navigation, grid of playlist cards, and a persistent bottom player bar — great for CSS Grid + sticky positioning. It also provides practice with persistent navigation, independently scrolling regions, responsive grids, player controls, and layouts that must remain usable across screen sizes.

Think of it like this
A city bus
The driver's cabin and the ticket counter stay fixed while passengers move around inside. Spotify's layout is that bus: the sidebar and player bar stay put, and only the middle section scrolls through playlists.
Watch it happen
Who scrolls, who stays
scroll playlists
1/4You scroll. Only main has overflow-y: auto, so only it moves.
The big ideas
What you need to know
App shell with Grid
grid-template-areas places the sidebar, main and player, and the whole thing fills the screen height.
Only main scrolls
The body doesn't scroll. The main area gets overflow-y: auto, so the sidebar and player stay visible.
Custom range slider
Style input type="range" for the progress and volume bars instead of building them from divs.
Playlist card grid
auto-fill with minmax makes the album grid fit any screen width.
How it works
Build plan
- 1
App shell
Grid with sidebar, main and player areas filling 100dvh.
- 2
Sidebar
Logo, Home, Search, Your Library links and a playlist list.
- 3
Main content
Greeting header and a responsive grid of playlist cards.
- 4
Player bar
Song info, play controls, progress slider and volume.
- 5
Mobile layout
Hide the sidebar and move the main links to a bottom bar under 768px.
See it in code
Walk through the code
1.app {2 display: grid;3 grid-template-columns: 280px 1fr;4 grid-template-rows: 1fr auto;5 grid-template-areas: "sidebar main" "player player";6 height: 100dvh;7}8.sidebar { grid-area: sidebar; overflow-y: auto; }9.main { grid-area: main; overflow-y: auto; }10.player { grid-area: player; }11 12@media (max-width: 767px) {13 .app { grid-template-columns: 1fr; grid-template-areas: "main" "player"; }14 .sidebar { display: none; }15}1/4A one-screen-tall grid: sidebar and main on top, player across the bottom.
The grid is exactly one screen tall. main has its own scrollbar, so the player bar never scrolls away.
Save yourself the pain
Common mistakes
Oops
Using position: fixed for the player and adding padding to guess its height.
Do this instead
Make it a grid row. The layout reserves its space automatically.
Oops
Building the progress bar from nested divs with no keyboard support.
Do this instead
Style a real <input type="range"> so arrow keys and screen readers work.
Your mission
First milestone: the shell
Quick check
In your Spotify layout, the whole page scrolls and the player bar disappears off screen. What's the likely fix?
Go deeper
- 1Build the fixed sidebar + scrollable main content layout with Grid. Keep the first version small, then add one improvement after the core behavior works.
- 2Recreate the sticky bottom player bar using `position: fixed`. Validate your understanding by applying it in a small practical example.
- 3Practice a responsive card grid for playlists using `repeat(auto-fill, ...)`.
More projects at this stop
Stuck on this topic? Ask an Insider
Get 1:1 guidance from people who've walked this exact path — on the InsideEdge app.