
Spotify clone
Prompt
Create a clone of the Spotify web/desktop app
A system prompt was added to support web rendering
Of course! Here is a functional, visual clone of the Spotify desktop application's user interface, built with HTML, CSS, and a small amount of JavaScript for interactivity. This single file includes all necessary assets, like icons from Font Awesome, to render correctly. ```html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Spotify Clone</title> <!-- Font Awesome for Icons --> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css"> <style> /* --- Universal Styles & Variables --- */ :root { --spotify-green: #1DB954; --light-green: #1ed760; --background-base: #121212; --background-highlight: #1A1A1A; --background-press: #000; --text-base: #FFFFFF; --text-subdued: #B3B3B3; --text-press: #FFFFFF; --sidebar-width: 280px; } * { box-sizing: border-box; margin: 0; padding: 0; } body { font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; background-color: var(--background-press); color: var(--text-base); overflow: hidden; /* Prevents whole page from scrolling */ } a { color: var(--text-subdued); text-decoration: none; } a:hover { color: var(--text-base); } /* --- Main Layout Grid --- */ .spotify-container { display: grid; grid-template-areas: "sidebar main-view" "player-bar player-bar"; grid-template-columns: var(--sidebar-width) 1fr; grid-template-rows: 1fr auto; height: 100vh; width: 100vw; } /* --- Sidebar --- */ .sidebar { grid-area: sidebar; background-color: #000; padding: 24px; display: flex; flex-direction: column; gap: 20px; } .sidebar .logo { font-size: 1.5rem; font-weight: bold; display: flex; align-items: center; gap: 8px; margin-bottom: 18px; } .logo i { font-size: 2.2rem; } .sidebar-section { background-color: var(--background-base); border-radius: 8px; padding: 8px 12px; } .sidebar nav ul { list-style: none; } .sidebar nav ul li a { display: flex; align-items: center; gap: 20px; padding: 10px; font-weight: 600; font-size: 1rem; transition: color 0.2s; } .sidebar nav ul li a.active { color: var(--text-base); } .sidebar nav ul li i { font-size: 1.5rem; width: 30px; /* To align text */ } .library .lib-header { display:flex; justify-content: space-between; align-items: center; padding: 10px; margin-bottom: 10px; } .library .lib-header a { display: flex; align-items: center; gap: 20px; font-weight: 600; } .library .lib-header .lib-icons button { background: none; border: none; color: var(--text-subdued); font-size: 1.2rem; cursor: pointer; padding: 5px; border-radius: 50%; } .library .lib-header .lib-icons button:hover { background-color: var(--background-highlight); color: var(--text-base); } .library-items { list-style: none; max-height: 40vh; /* Adjust as needed */ overflow-y: auto; /* Custom Scrollbar */ scrollbar-width: thin; scrollbar-color: var(--text-subdued) transparent; } .library-items::-webkit-scrollbar { width: 8px; } .library-items::-webkit-scrollbar-thumb { background-color: var(--text-subdued); border-radius: 4px; } .library-items::-webkit-scrollbar-track { background: transparent; } .library-item { display: flex; align-items: center; gap: 12px; padding: 8px; border-radius: 6px; cursor: pointer; transition: background-color 0.2s; } .library-item:hover { background-color: var(--background-highlight); } .library-item img { width: 50px; height: 50px; border-radius: 4px; object-fit: cover; } .library-item .item-info h4 { font-size: 0.9rem; margin: 0; } .library-item .item-info p { font-size: 0.8rem; color: var(--text-subdued); } /* --- Main View --- */ .main-view { grid-area: main-view; background: linear-gradient(to bottom, #222 0%, #121212 25%); overflow-y: auto; /* Custom Scrollbar */ scrollbar-width: thin; scrollbar-color: var(--text-subdued) transparent; } .main-view::-webkit-scrollbar { width: 12px; } .main-view::-webkit-scrollbar-thumb { background-color: var(--text-subdued); border-radius: 6px; } .main-view::-webkit-scrollbar-track { background: transparent; } .main-header { position: sticky; top: 0; padding: 16px 32px; display: flex; justify-content: space-between; align-items: center; z-index: 10; } .main-header .nav-buttons button { background-color: rgba(0,0,0,0.5); border: none; color: var(--text-base); width: 32px; height: 32px; border-radius: 50%; cursor: pointer; margin-right: 16px; } .main-header .user-profile button { background-color: rgba(0,0,0,0.7); border: none; color: var(--text-base); padding: 4px 12px 4px 4px; border-radius: 23px; display: flex; align-items: center; gap: 8px; cursor: pointer; } .main-header .user-profile button:hover { background-color: #282828; } .user-profile .avatar { background-color: #535353; width: 28px; height: 28px; border-radius: 50%; display:flex; align-items: center; justify-content: center; } .content { padding: 16px 32px; } .content-section h2 { font-size: 1.8rem; margin-bottom: 24px; } .card-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); gap: 24px; } .card { background-color: var(--background-highlight); padding: 16px; border-radius: 8px; cursor: pointer; transition: background-color 0.3s; position: relative; } .card:hover { background-color: #282828; } .card img { width: 100%; border-radius: 6px; margin-bottom: 12px; box-shadow: 0 8px 24px rgba(0,0,0,0.5); } .card h3 { font-size: 1rem; margin-bottom: 4px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .card p { font-size: 0.9rem; color: var(--text-subdued); overflow: hidden; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; } .card .play-button { position: absolute; right: 24px; bottom: 90px; width: 50px; height: 50px; background-color: var(--spotify-green); border-radius: 50%; display: flex; align-items: center; justify-content: center; color: #000; font-size: 1.5rem; opacity: 0; transform: translateY(10px); transition: all 0.3s ease; box-shadow: 0 8px 8px rgba(0,0,0,0.3); } .card:hover .play-button { opacity: 1; transform: translateY(0); } .card .play-button:hover { transform: scale(1.05); background-color: var(--light-green); } /* --- Player Bar --- */ .player-bar { grid-area: player-bar; background-color: #181818; border-top: 1px solid #282828; padding: 12px 16px; display: grid; grid-template-columns: 1fr 2fr 1fr; align-items: center; gap: 20px; height: 90px; } .player-now-playing { display: flex; align-items: center; gap: 12px; } .player-now-playing img { width: 56px; height: 56px; border-radius: 4px; } .player-now-playing .song-info h4 { font-size: 0.9rem; } .player-now-playing .song-info p { font-size: 0.7rem; color: var(--text-subdued); } .player-now-playing .like-button { background: none; border: none; color: var(--text-subdued); font-size: 1.2rem; cursor: pointer; } .player-controls { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 8px; } .player-buttons { display: flex; align-items: center; gap: 16px; } .player-buttons button { background: none; border: none; color: var(--text-subdued); font-size: 1.1rem; cursor: pointer; transition: color 0.2s; } .player-buttons button:hover { color: var(--text-base); } .player-buttons .play-pause-btn { background-color: var(--text-base); color: #000; width: 32px; height: 32px; border-radius: 50%; display: flex; align-items: center; justify-content: center; font-size: 1rem; transition: transform 0.2s; } .player-buttons .play-pause-btn:hover { transform: scale(1.05); } .playback-bar { display: flex; align-items: center; gap: 8px; width: 100%; max-width: 500px; } .playback-bar .progress-bar { flex-grow: 1; height: 4px; background-color: #535353; border-radius: 2px; cursor: pointer; } .progress-bar .progress { width: 30%; height: 100%; background-color: var(--text-base); border-radius: 2px; } .playback-bar span { font-size: 0.7rem; color: var(--text-subdued); } .player-options { display: flex; justify-content: flex-end; align-items: center; gap: 16px; } .player-options button { background: none; border: none; color: var(--text-subdued); font-size: 1.1rem; cursor: pointer; } .player-options button:hover { color: var(--text-base); } .player-options .volume-control { display: flex; align-items: center; gap: 8px; } .volume-control .progress-bar { width: 80px; } .volume-control .progress { width: 80%; } </style> </head> <body> <div class="spotify-container"> <!-- Sidebar --> <aside class="sidebar"> <div class="logo"> <i class="fab fa-spotify"></i> <span>Spotify</span> </div> <div class="sidebar-section"> <nav> <ul> <li><a href="#" class="active"><i class="fas fa-home"></i> Home</a></li> <li><a href="#"><i class="fas fa-search"></i> Search</a></li> </ul> </nav> </div> <div class="sidebar-section library"> <div class="lib-header"> <a href="#"> <i class="fas fa-book"></i> Your Library </a> <div class="lib-icons"> <button><i class="fas fa-plus"></i></button> </div> </div> <ul class="library-items"> <li class="library-item"> <img src="https://picsum.photos/id/1015/50/50" alt="Album Art"> <div class="item-info"> <h4>Liked Songs</h4> <p>Playlist • 345 songs</p> </div> </li> <li class="library-item"> <img src="https://picsum.photos/id/20/50/50" alt="Album Art"> <div class="item-info"> <h4>Indie Poptimism</h4> <p>Playlist • Spotify</p> </div> </li> <li class="library-item"> <img src="https://picsum.photos/id/237/50/50" alt="Album Art"> <div class="item-info"> <h4>Canine Core</h4> <p>Playlist • You</p> </div> </li> <li class="library-item"> <img src="https://picsum.photos/id/42/50/50" alt="Album Art"> <div class="item-info"> <h4>Release Radar</h4> <p>Playlist • Spotify</p> </div> </li> <li class="library-item"> <img src="https://picsum.photos/id/111/50/50" alt="Album Art"> <div class="item-info"> <h4>Daily Mix 1</h4> <p>Playlist • Spotify</p> </div> </li> </ul> </div> </aside> <!-- Main Content --> <main class="main-view"> <header class="main-header"> <div class="nav-buttons"> <button><i class="fas fa-chevron-left"></i></button> <button><i class="fas fa-chevron-right"></i></button> </div> <div class="user-profile"> <button> <div class="avatar"><i class="fas fa-user"></i></div> <span>Your Name</span> </button> </div> </header> <div class="content"> <section class="content-section"> <h2>Good Afternoon</h2> <div class="card-grid"> <div class="card"> <img src="https://picsum.photos/id/10/300/300" alt="Album Art"> <h3>Lofi Beats</h3> <p>Chillhop, instrumental hip-hop</p> <div class="play-button"><i class="fas fa-play"></i></div> </div> <div class="card"> <img src="https://picsum.photos/id/40/300/300" alt="Album Art"> <h3>Today's Top Hits</h3> <p>The biggest songs of the moment</p> <div class="play-button"><i class="fas fa-play"></i></div> </div> <div class="card"> <img src="https://picsum.photos/id/103/300/300" alt="Album Art"> <h3>Rock Classics</h3> <p>Legendary rock anthems</p> <div class="play-button"><i class="fas fa-play"></i></div> </div> <div class="card"> <img src="https://picsum.photos/id/1011/300/300" alt="Album Art"> <h3>Peaceful Piano</h3> <p>Relax and indulge with beautiful piano pieces</p> <div class="play-button"><i class="fas fa-play"></i></div> </div> <div class="card"> <img src="https://picsum.photos/id/211/300/300" alt="Album Art"> <h3>RapCaviar</h3> <p>The freshest rap and hip-hop tracks</p> <div class="play-button"><i class="fas fa-play"></i></div> </div> </div> </section> <section class="content-section"> <h2>Your Shows</h2> <div class="card-grid"> <div class="card"> <img src="https://picsum.photos/id/351/300/300" alt="Album Art"> <h3>Tech Tomorrow</h3> <p>Show • Tech News Weekly</p> <div class="play-button"><i class="fas fa-play"></i></div> </div> <div class="card"> <img src="https://picsum.photos/id/366/300/300" alt="Album Art"> <h3>Deep Dive History</h3> <p>Show • History Uncovered</p> <div class="play-button"><i class="fas fa-play"></i></div> </div> <div class="card"> <img src="https://picsum.photos/id/823/300/300" alt="Album Art"> <h3>The Daily</h3> <p>Show • The New York Times</p> <div class="play-button"><i class="fas fa-play"></i></div> </div> </div> </section> </div> </main> <!-- Player Bar --> <footer class="player-bar"> <div class="player-now-playing"> <img src="https://picsum.photos/id/10/56/56" alt="Now Playing Album Art"> <div class="song-info"> <h4>Forest Fantasia</h4> <p>Lofi Beats</p> </div> <button class="like-button"><i class="far fa-heart"></i></button> </div> <div class="player-controls"> <div class="player-buttons"> <button><i class="fas fa-shuffle"></i></button> <button><i class="fas fa-backward-step"></i></button> <button class="play-pause-btn" id="play-pause"> <i class="fas fa-pause"></i> </button> <button><i class="fas fa-forward-step"></i></button> <button><i class="fas fa-repeat"></i></button> </div> <div class="playback-bar"> <span>1:12</span> <div class="progress-bar"><div class="progress"></div></div> <span>3:45</span> </div> </div> <div class="player-options"> <button><i class="fas fa-microphone-alt"></i></button> <button><i class="fas fa-bars"></i></button> <button><i class="fas fa-desktop"></i></button> <div class="volume-control"> <button><i class="fas fa-volume-high"></i></button> <div class="progress-bar"><div class="progress"></div></div> </div> </div> </footer> </div> <script> const playPauseBtn = document.getElementById('play-pause'); const icon = playPauseBtn.querySelector('i'); let isPlaying = true; playPauseBtn.addEventListener('click', () => { if (isPlaying) { icon.classList.remove('fa-pause'); icon.classList.add('fa-play'); } else { icon.classList.remove('fa-play'); icon.classList.add('fa-pause'); } isPlaying = !isPlaying; }); </script> </body> </html> ```
Drag to resize
# Spotify Web App Clone I'll create a responsive Spotify clone with sidebar navigation, main content area, and player controls. Here's the complete implementation: ```html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Spotify Clone</title> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> <link href="https://fonts.googleapis.com/css2?family=Montserrat:wght@400;500;600;700&display=swap" rel="stylesheet"> <style> * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Montserrat', sans-serif; } body { background-color: #121212; color: #fff; height: 100vh; overflow: hidden; } .app-container { display: flex; flex-direction: column; height: 100vh; } /* Top Navigation */ .top-nav { display: flex; justify-content: space-between; align-items: center; padding: 16px 32px; background-color: rgba(0, 0, 0, 0.6); position: sticky; top: 0; z-index: 10; } .nav-buttons { display: flex; gap: 16px; } .nav-btn { background-color: rgba(0, 0, 0, 0.7); border: none; border-radius: 50%; width: 32px; height: 32px; color: #fff; cursor: pointer; display: flex; align-items: center; justify-content: center; } .search-container { display: flex; align-items: center; background-color: #fff; border-radius: 20px; padding: 6px 12px; width: 300px; } .search-container input { background: transparent; border: none; outline: none; color: #121212; width: 100%; font-size: 14px; } .user-profile { display: flex; align-items: center; gap: 8px; background-color: rgba(0, 0, 0, 0.7); border-radius: 20px; padding: 4px 8px; cursor: pointer; } .user-profile img { width: 28px; height: 28px; border-radius: 50%; object-fit: cover; } /* Main Content */ .main-content { display: flex; flex: 1; overflow: hidden; } /* Sidebar */ .sidebar { width: 240px; background-color: #000; padding: 24px 12px; overflow-y: auto; } .logo { padding: 0 12px 24px; } .logo img { width: 130px; } .nav-item { display: flex; align-items: center; padding: 12px; border-radius: 4px; margin-bottom: 4px; cursor: pointer; transition: background-color 0.2s; } .nav-item:hover { background-color: #282828; } .nav-item i { margin-right: 16px; font-size: 20px; } .nav-item.active { background-color: #282828; } .playlists { margin-top: 24px; padding: 0 12px; } .playlists h3 { font-size: 12px; text-transform: uppercase; letter-spacing: 1px; margin-bottom: 16px; color: #b3b3b3; } .playlist-item { padding: 8px 0; color: #b3b3b3; cursor: pointer; } .playlist-item:hover { color: #fff; } .install-app { display: flex; align-items: center; margin-top: 24px; padding: 0 12px; color: #b3b3b3; cursor: pointer; } .install-app i { margin-right: 16px; font-size: 20px; } /* Content Area */ .content-area { flex: 1; padding: 24px 32px; overflow-y: auto; background: linear-gradient(to bottom, #3d0963, #121212); } .greeting { font-size: 32px; font-weight: 700; margin-bottom: 24px; } .card-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); gap: 24px; margin-bottom: 40px; } .card { background-color: #181818; border-radius: 6px; padding: 16px; transition: background-color 0.3s; cursor: pointer; } .card:hover { background-color: #282828; } .card-img { width: 100%; aspect-ratio: 1/1; border-radius: 4px; margin-bottom: 16px; box-shadow: 0 8px 16px rgba(0, 0, 0, 0.3); } .card-title { font-weight: 700; margin-bottom: 8px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .card-desc { font-size: 14px; color: #b3b3b3; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; } .section-title { font-size: 24px; font-weight: 700; margin: 32px 0 16px; } /* Player */ .player { height: 90px; background-color: #181818; border-top: 1px solid #282828; display: flex; align-items: center; padding: 0 16px; position: relative; } .now-playing { display: flex; align-items: center; width: 30%; } .now-playing img { width: 56px; height: 56px; border-radius: 4px; margin-right: 14px; } .track-info { display: flex; flex-direction: column; } .track-name { font-weight: 500; font-size: 14px; } .track-artist { font-size: 12px; color: #b3b3b3; } .player-controls { display: flex; flex-direction: column; align-items: center; width: 40%; } .control-buttons { display: flex; align-items: center; gap: 16px; margin-bottom: 8px; } .control-btn { background: none; border: none; color: #b3b3b3; font-size: 16px; cursor: pointer; } .control-btn.play-btn { background-color: #fff; color: #000; width: 32px; height: 32px; border-radius: 50%; display: flex; align-items: center; justify-content: center; } .control-btn:hover { color: #fff; } .progress-container { width: 100%; display: flex; align-items: center; gap: 8px; } .progress-time { font-size: 12px; color: #b3b3b3; min-width: 40px; } .progress-bar { flex: 1; height: 4px; background-color: #535353; border-radius: 2px; position: relative; cursor: pointer; } .progress-bar:hover { background-color: #5e5e5e; } .progress-fill { position: absolute; height: 100%; width: 30%; background-color: #b3b3b3; border-radius: 2px; } .progress-fill:hover { background-color: #1db954; } .volume-controls { display: flex; align-items: center; gap: 8px; width: 30%; justify-content: flex-end; } .volume-bar { width: 100px; height: 4px; background-color: #535353; border-radius: 2px; position: relative; cursor: pointer; } .volume-fill { position: absolute; height: 100%; width: 70%; background-color: #b3b3b3; border-radius: 2px; } .volume-fill:hover { background-color: #1db954; } /* Responsive */ @media (max-width: 768px) { .sidebar { width: 70px; } .nav-item span, .playlists h3, .playlist-item, .install-app span { display: none; } .nav-item { justify-content: center; } .nav-item i { margin-right: 0; } .search-container { width: 200px; } .card-grid { grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); } } </style> </head> <body> <div class="app-container"> <!-- Top Navigation --> <div class="top-nav"> <div class="nav-buttons"> <button class="nav-btn"><i class="fas fa-chevron-left"></i></button> <button class="nav-btn"><i class="fas fa-chevron-right"></i></button> </div> <div class="search-container"> <i class="fas fa-search" style="color: #121212;"></i> <input type="text" placeholder="Search"> </div> <div class="user-profile"> <img src="https://randomuser.me/api/portraits/men/32.jpg" alt="User"> <span>John Doe</span> <i class="fas fa-caret-down"></i> </div> </div> <!-- Main Content --> <div class="main-content"> <!-- Sidebar --> <div class="sidebar"> <div class="logo"> <img src="https://storage.googleapis.com/pr-newsroom-wp/1/2018/11/Spotify_Logo_RGB_White.png" alt="Spotify"> </div> <div class="nav-item active"> <i class="fas fa-home"></i> <span>Home</span> </div> <div class="nav-item"> <i class="fas fa-search"></i> <span>Search</span> </div> <div class="nav-item"> <i class="fas fa-book"></i> <span>Your Library</span> </div> <div class="nav-item"> <i class="fas fa-plus-square"></i> <span>Create Playlist</span> </div> <div class="nav-item"> <i class="fas fa-heart"></i> <span>Liked Songs</span> </div> <div class="playlists"> <h3>Playlists</h3> <div class="playlist-item">Discover Weekly</div> <div class="playlist-item">Release Radar</div> <div class="playlist-item">Chill Vibes</div> <div class="playlist-item">Workout Mix</div> <div class="playlist-item">Road Trip</div> <div class="playlist-item">Study Focus</div> <div class="playlist-item">Throwback Hits</div> <div class="playlist-item">Indie Mix</div> </div> <div class="install-app"> <i class="fas fa-download"></i> <span>Install App</span> </div> </div> <!-- Content Area --> <div class="content-area"> <h1 class="greeting">Good evening</h1> <div class="card-grid"> <div class="card"> <img src="https://i.scdn.co/image/ab67706f00000002ca5a7517156021292e5663a6" alt="Album" class="card-img"> <div class="card-title">Daily Mix 1</div> <div class="card-desc">Made for you based on your listening history</div> </div> <div class="card"> <img src="https://i.scdn.co/image/ab67706f00000002d72ef75e14ca6f5d39b775b1" alt="Album" class="card-img"> <div class="card-title">Discover Weekly</div> <div class="card-desc">Your weekly mixtape of fresh music</div> </div> <div class="card"> <img src="https://i.scdn.co/image/ab67706f00000002a980b15037e61d1d7b57ffd1" alt="Album" class="card-img"> <div class="card-title">Release Radar</div> <div class="card-desc">Catch all the latest music from artists you follow</div> </div> <div class="card"> <img src="https://i.scdn.co/image/ab67706f00000002a76a2ccb454ff0e1720a51db" alt="Album" class="card-img"> <div class="card-title">Chill Vibes</div> <div class="card-desc">Relaxing beats and melodies for your downtime</div> </div> <div class="card"> <img src="https://i.scdn.co/image/ab67706f00000002a980b15037e61d1d7b57ffd1" alt="Album" class="card-img"> <div class="card-title">Workout Mix</div> <div class="card-desc">High-energy tracks to power your exercise</div> </div> <div class="card"> <img src="https://i.scdn.co/image/ab67706f00000002a76a2ccb454ff0e1720a51db" alt="Album" class="card-img"> <div class="card-title">Road Trip</div> <div class="card-desc">The perfect soundtrack for your journey</div> </div> </div> <h2 class="section-title">Made for you</h2> <div class="card-grid"> <div class="card"> <img src="https://i.scdn.co/image/ab67706f00000002a980b15037e61d1d7b57ffd1" alt="Album" class="card-img"> <div class="card-title">Daily Mix 2</div> <div class="card-desc">Featuring artists you love and new discoveries</div> </div> <div class="card"> <img src="https://i.scdn.co/image/ab67706f00000002ca5a7517156021292e5663a6" alt="Album" class="card-img"> <div class="card-title">Throwback Thursday</div> <div class="card-desc">Classic hits from the 80s, 90s, and 2000s</div> </div> <div class="card"> <img src="https://i.scdn.co/image/ab67706f00000002d72ef75e14ca6f5d39b775b1" alt="Album" class="card-img"> <div class="card-title">Indie Mix</div> <div class="card-desc">The best new independent artists</div> </div> <div class="card"> <img src="https://i.scdn.co/image/ab67706f00000002a76a2ccb454ff0e1720a51db" alt="Album" class="card-img"> <div class="card-title">Study Focus</div> <div class="card-desc">Concentration-enhancing tracks</div> </div> </div> </div> </div> <!-- Player --> <div class="player"> <div class="now-playing"> <img src="https://i.scdn.co/image/ab67616d00001e02ff9ca10b55ce82ae553c8228" alt="Now Playing"> <div class="track-info"> <div class="track-name">Blinding Lights</div> <div class="track-artist">The Weeknd</div> </div> <i class="fas fa-heart" style="margin-left: 16px; color: #b3b3b3;"></i> </div> <div class="player-controls"> <div class="control-buttons"> <button class="control-btn"><i class="fas fa-random"></i></button> <button class="control-btn"><i class="fas fa-step-backward"></i></button> <button class="control-btn play-btn"><i class="fas fa-play"></i></button> <button class="control-btn"><i class="fas fa-step-forward"></i></button> <button class="control-btn"><i class="fas fa-repeat"></i></button> </div> <div class="progress-container"> <div class="progress-time">1:23</div> <div class="progress-bar"> <div class="progress-fill"></div> </div> <div class="progress-time">3:45</div> </div> </div> <div class="volume-controls"> <button class="control-btn"><i class="fas fa-list"></i></button> <button class="control-btn"><i class="fas fa-laptop"></i></button> <button class="control-btn"><i class="fas fa-volume-up"></i></button> <div class="volume-bar"> <div class="volume-fill"></div> </div> </div> </div> </div> <script> // Simple interactions document.addEventListener('DOMContentLoaded', function() { // Toggle active state for nav items const navItems = document.querySelectorAll('.nav-item'); navItems.forEach(item => { item.addEventListener('click', function() { navItems.forEach(i => i.classList.remove('active')); this.classList.add('active'); }); }); // Play button toggle const playBtn = document.querySelector('.play-btn'); playBtn.addEventListener('click', function() { const icon = this.querySelector('i'); if (icon.classList.contains('fa-play')) { icon.classList.remove('fa-play'); icon.classList.add('fa-pause'); } else { icon.classList.remove('fa-pause'); icon.classList.add('fa-play'); } }); // Card hover effect const cards = document.querySelectorAll('.card'); cards.forEach(card => { card.addEventListener('mouseenter', function() { this.style.transform = 'scale(1.03)'; }); card.addEventListener('mouseleave', function() { this.style.transform = 'scale(1)'; }); }); }); </script> </body> </html> ``` This Spotify clone includes: 1. **Top Navigation** with back/forward buttons, search bar, and user profile 2. **Sidebar** with navigation items and playlists (collapses on smaller screens) 3. **Main Content Area** with: - Personalized greeting - Grid of playlist cards - Multiple sections for different content types 4. **Music Player** at the bottom with: - Current track information - Playback controls - Progress bar - Volume controls The design uses Spotify's dark theme with purple gradients and responsive layout that adapts to different screen sizes. The JavaScript adds basic interactivity like navigation selection, play/pause toggle, and hover effects. You can copy this entire code into an HTML file and open it in any browser to see the Spotify clone in action.
Drag to resize
```html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Spotify Clone</title> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <!-- Google Fonts CDN --> <link href="https://fonts.googleapis.com/css?family=Montserrat:400,700&display=swap" rel="stylesheet"> <!-- Font Awesome for icons --> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.2/css/all.min.css"> <style> :root { --sidebar-width: 235px; --player-height: 90px; --primary: #1db954; --bg: #181818; --bg-dark: #121212; --bg-light: #282828; --text: #fff; --text-muted: #b3b3b3; } * {box-sizing: border-box;} body { margin: 0; font-family: 'Montserrat', Arial, sans-serif; background: var(--bg-dark); color: var(--text); height: 100vh; overflow: hidden; } #app { display: flex; flex-direction: column; height: 100vh; } .main-body { flex: 1 1 auto; display: flex; min-height: 0; } .sidebar { width: var(--sidebar-width); background: var(--bg); padding: 24px 0 0 0; display: flex; flex-direction: column; height: 100%; } .logo { text-align: center; margin-bottom: 30px; } .logo img { width: 130px; } .side-nav, .side-library { list-style: none; padding: 0; margin: 0 0 12px 0; } .side-nav li, .side-library li { padding: 12px 0 12px 32px; cursor: pointer; font-size: 15px; color: var(--text-muted); display: flex; align-items: center; transition: background 0.1s; } .side-nav li.active, .side-nav li:hover, .side-library li:hover {color: var(--text);background: var(--bg-light);} .side-nav i, .side-library i { margin-right: 18px; font-size: 19px; } .side-library-header { padding: 18px 0 8px 32px; font-size: 14px; text-transform: uppercase; color: var(--text-muted); letter-spacing: 1px; } .playlist-btn { background: var(--bg-light); color: var(--text-muted); text-align: left; border: none; width: 170px; margin: 14px 0 0 32px; padding: 10px 16px; border-radius: 20px; cursor: pointer; font-size: 14px; transition: background 0.2s; display: flex; align-items: center; gap: 8px; } .playlist-btn:hover {background: var(--primary);color: var(--bg-dark);} /* Main content */ .main-content { flex: 1 1 auto; background: linear-gradient(180deg, #2e2e2e 0%, var(--bg-dark) 100%); overflow-y: auto; padding-bottom: 90px; /* Space for the player */ } .header { padding: 24px 36px 16px 36px; display: flex; justify-content: space-between; align-items: center; position: sticky; top: 0; background: linear-gradient(180deg, #232323 60%, transparent 100%); z-index: 2; } .header-left { display: flex; gap: 14px; } .circle-btn { width: 34px; height: 34px; background: var(--bg-light); color: var(--text-muted); border: none; border-radius: 50%; font-size: 17px; cursor: pointer; display: flex; align-items: center; justify-content: center; transition: background 0.2s; } .circle-btn:hover {background: #393939; color: #fff;} .header-right { display: flex; align-items: center; gap: 18px; } .profile-img { width: 36px; height: 36px; border-radius: 50%; object-fit: cover; border: 2px solid var(--primary); } .welcome { font-size: 30px; font-weight: bold; margin: 26px 0 8px 36px; } /* playlist section */ .playlist-section { padding: 0 36px; } .playlist-row { font-size: 21px; font-weight: 700; margin: 28px 0 8px 0; } .playlist-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: 28px; } .playlist-card { background: var(--bg); border-radius: 7px; padding: 17px; cursor: pointer; display: flex; flex-direction: column; align-items: start; transition: background 0.18s, transform 0.16s; } .playlist-card:hover { background: #222; transform: translateY(-2px) scale(1.025); } .playlist-image { width: 100%; aspect-ratio: 1/1; border-radius: 7px; object-fit: cover; margin-bottom: 15px; } .playlist-title { font-size: 17px; font-weight: 600; margin-bottom: 6px; } .playlist-desc { color: var(--text-muted); font-size: 14px; } /* Player bar */ .player { position: fixed; left: 0; right: 0; bottom: 0; height: var(--player-height); background: linear-gradient(90deg,#282828 65%, #181818 100%); color: #fff; display: flex; align-items: center; padding: 0 20px; z-index: 4; box-shadow: 0 -1px 16px #2228; } .player-song { display: flex; align-items: center; min-width: 200px; max-width: 24vw; flex: 0 0 290px; } .player-song img { width: 54px; height: 54px; border-radius: 6px; } .player-song-info { margin-left: 13px; overflow: hidden; } .player-song-title { font-size: 15px; font-weight: 600; text-overflow: ellipsis; overflow: hidden; white-space: nowrap; margin: 4px 0 0 0; } .player-song-artist { color: var(--text-muted); font-size: 13px; text-overflow: ellipsis; overflow: hidden; white-space: nowrap; } .player-controls { flex: 1; display: flex; flex-direction: column; align-items: center; gap: 7px; min-width: 0; } .player-controls-buttons { display: flex; align-items: center; gap: 23px; } .player-controls .fa-shuffle, .player-controls .fa-repeat { color: var(--text-muted); font-size: 16px; cursor: pointer; transition: color 0.15s; } .player-controls .fa-play, .player-controls .fa-pause { color: #222; /* For contrast */ background: #fff; border-radius: 50%; font-size: 19px; padding: 8px 12px; box-shadow: 0 2px 10px #0003; cursor: pointer; border: none; margin: 0 8px; transition: background .13s, color .16s; } .player-controls .fa-play:hover, .player-controls .fa-pause:hover {background: var(--primary); color: #fff;} .player-progress { display: flex; align-items: center; gap: 10px; width: 50vw; min-width: 200px; max-width: 500px; } .player-timestamp { font-size: 13px; color: var(--text-muted); min-width: 42px; text-align: right; } .progress-bar { flex: 1; height: 5px; background: #4a4a4a; border-radius: 10px; cursor: pointer; position: relative; } .progress-filled { height: 100%; background: var(--primary); border-radius: 10px; width: 0; transition: width 0.1s; } /* player right */ .player-extra { min-width: 186px; display: flex; align-items: center; justify-content: flex-end; gap: 19px; flex: 0 0 220px; } .player-extra i { color: var(--text-muted); font-size: 18px; cursor: pointer; } .volume-bar { width: 88px; height: 5px; background: #444; border-radius: 8px; overflow: hidden; cursor: pointer; display: inline-block; } .volume-filled { background: var(--primary); height: 100%; width: 70%; transition: width 0.12s; } /* scrollbar styles */ ::-webkit-scrollbar {width: 8px;background:transparent;} ::-webkit-scrollbar-thumb {background: #1d1d1d; border-radius: 6px;} @media (max-width: 900px) { .sidebar {display: none;} .main-content {padding: 0;} .header, .welcome, .playlist-section {padding-left:12px;padding-right:12px;} .player {flex-direction: column; height: auto;} .player-song, .player-controls, .player-extra {flex:initial;} .player-song {margin-bottom:8px;} .player-progress {width:100%;} } </style> </head> <body> <div id="app"> <div class="main-body"> <aside class="sidebar"> <div class="logo"> <img src="https://upload.wikimedia.org/wikipedia/commons/1/19/Spotify_logo_without_text.svg" alt="Spotify Logo"> </div> <ul class="side-nav"> <li class="active"><i class="fa-solid fa-house"></i> Home</li> <li><i class="fa-solid fa-magnifying-glass"></i> Search</li> <li><i class="fa-solid fa-book"></i> Your Library</li> </ul> <div class="side-library-header">Playlists</div> <ul class="side-library" id="playlistList"> <li><i class="fa-solid fa-plus"></i> Create Playlist</li> <li><i class="fa-solid fa-heart"></i> Liked Songs</li> </ul> <button class="playlist-btn" id="createPlaylist"> <i class="fa-solid fa-plus"></i> New Playlist </button> </aside> <main class="main-content" id="mainContent"> <div class="header"> <div class="header-left"> <button class="circle-btn" title="Back" disabled><i class="fa-solid fa-chevron-left"></i></button> <button class="circle-btn" title="Forward" disabled><i class="fa-solid fa-chevron-right"></i></button> </div> <div class="header-right"> <i class="fa-solid fa-bell"></i> <img class="profile-img" src="https://randomuser.me/api/portraits/men/35.jpg" alt="Profile"> </div> </div> <div class="welcome">Good afternoon</div> <div class="playlist-section"> <div class="playlist-row">Your Top Mixes</div> <div class="playlist-grid" id="playlistGrid"></div> <div class="playlist-row" style="margin-top:44px;">Made For You</div> <div class="playlist-grid" id="madeGrid"></div> </div> </main> </div> <footer class="player" id="player"> <div class="player-song" id="playerSong"> <img src="https://i.scdn.co/image/ab67616d0000b2731c50e5fbf2cb7b9e8d83b7a5" alt="Album artwork"> <div class="player-song-info"> <div class="player-song-title">Blinding Lights</div> <div class="player-song-artist">The Weeknd</div> </div> </div> <div class="player-controls"> <div class="player-controls-buttons"> <i class="fa-solid fa-shuffle"></i> <i class="fa-solid fa-backward-step" id="prevBtn"></i> <button class="fa-solid fa-play" id="playPauseBtn"></button> <i class="fa-solid fa-forward-step" id="nextBtn"></i> <i class="fa-solid fa-repeat"></i> </div> <div class="player-progress"> <div class="player-timestamp" id="curTime">0:00</div> <div class="progress-bar" id="progressBar"> <div class="progress-filled" id="progressFill"></div> </div> <div class="player-timestamp" id="totalTime">3:20</div> </div> </div> <div class="player-extra"> <i class="fa-solid fa-microphone"></i> <i class="fa-solid fa-bars"></i> <i class="fa-solid fa-volume-high"></i> <div class="volume-bar" id="volumeBar"> <div class="volume-filled" id="volumeFilled"></div> </div> </div> <!-- Audio element (hidden) --> <audio id="audioPlayer"></audio> </footer> </div> <script> // Dummy data for playlists const playlists = [ { title: "Top Hits 2024", desc: "Your daily mix of hit songs.", image: "https://i.scdn.co/image/ab67706f000000029478f0b35a7b4a1e43cda47e", tracks: [ { title: "Blinding Lights", artist: "The Weeknd", image: "https://i.scdn.co/image/ab67616d0000b2731c50e5fbf2cb7b9e8d83b7a5", src: "https://cdn.pixabay.com/audio/2023/03/30/audio_127b71b240.mp3", // dummy public mp3 duration: 200 }, { title: "Save Your Tears", artist: "The Weeknd", image: "https://i.scdn.co/image/ab67616d0000b27327b1904e74c28f0ca0d875f7", src: "https://cdn.pixabay.com/audio/2023/02/22/audio_12ce7f7274.mp3", duration: 190 } ] }, { title: "Mellow Chill", desc: "Chill vibes, soft beats.", image: "https://i.scdn.co/image/ab67706f0000000283d6e63403060d5b9235156d", tracks: [ { title: "Ocean Eyes", artist: "Billie Eilish", image: "https://i.scdn.co/image/ab67616d0000b2732e8365a793102b66480d8f13", src: "https://cdn.pixabay.com/audio/2022/12/19/audio_12b2fdc8e1.mp3", duration: 212 } ] }, { title: "RapCaviar", desc: "Hip-hop's top tracks.", image: "https://i.scdn.co/image/ab67706f00000002c8c7610f36ed0fe58f05d2a8", tracks: [ { title: "Sicko Mode", artist: "Travis Scott", image: "https://i.scdn.co/image/ab67616d0000b2738d72e27e6b1e67e880962866", src: "https://cdn.pixabay.com/audio/2023/03/30/audio_127b71b240.mp3", duration: 250 } ] }, { title: "Peaceful Piano", desc: "Relax and focus with piano", image: "https://i.scdn.co/image/ab67706f0000000281ea150442b43b2781db96be", tracks: [ { title: "River Flows In You", artist: "Yiruma", image: "https://i.scdn.co/image/ab67616d0000b273d1eef8b98489c7937cddbd42", src: "https://cdn.pixabay.com/audio/2023/04/11/audio_12947bfa4b.mp3", duration: 183 } ] } ]; const madeForYou = [ { title: "Discover Weekly", desc: "Your weekly music discovery.", image: "https://i.scdn.co/image/ab67706f00000002d0a3ba4992b7e0d68feac375", tracks: playlists[1].tracks }, { title: "Release Radar", desc: "Music just released for you.", image: "https://i.scdn.co/image/ab67706f000000027b087c3e1fa9e406b64f1439", tracks: playlists[0].tracks } ]; // Render playlists function renderPlaylists() { const grid = document.getElementById('playlistGrid'); grid.innerHTML = ''; playlists.forEach((pl, idx) => { grid.innerHTML += ` <div class="playlist-card" onclick="openPlaylist(${idx})"> <img class="playlist-image" src="${pl.image}" alt="Playlist"> <div class="playlist-title">${pl.title}</div> <div class="playlist-desc">${pl.desc}</div> </div> `; }); // Made for you const mGrid = document.getElementById('madeGrid'); mGrid.innerHTML = ''; madeForYou.forEach((pl, idx) => { mGrid.innerHTML += ` <div class="playlist-card" onclick="openMadePlaylist(${idx})"> <img class="playlist-image" src="${pl.image}" alt="Playlist"> <div class="playlist-title">${pl.title}</div> <div class="playlist-desc">${pl.desc}</div> </div> `; }); } // Open a playlist view function openPlaylist(idx) { const pl = playlists[idx]; document.getElementById('mainContent').innerHTML = ` <div class="header"> <div class="header-left"> <button class="circle-btn" onclick="goHome()"><i class="fa-solid fa-chevron-left"></i></button> </div> <div class="header-right"> <i class="fa-solid fa-bell"></i> <img class="profile-img" src="https://randomuser.me/api/portraits/men/35.jpg" alt="Profile"> </div> </div> <div style="display:flex;align-items:end;gap:30px;margin:28px 0 34px 36px;"> <img src="${pl.image}" style="width:180px;height:180px;border-radius:10px;box-shadow:0 7px 24px #0006;"> <div> <div style="font-size:13px;color:var(--text-muted);margin-bottom:7px;">Playlist</div> <div style="font-size:38px;font-weight:800;margin-bottom:20px;">${pl.title}</div> <div style="color:var(--text-muted);">${pl.desc}</div> </div> </div> <div style="margin-left:36px;"> <button class="circle-btn" style="background:var(--primary);color:#fff;font-size:22px;width:52px;height:52px;" onclick="playPlaylist(${idx},0)"> <i class="fa-solid fa-play"></i> </button> </div> <table style="margin:36px 0 0 36px;min-width:350px;width:85%;color:var(--text);font-size:15px;border-collapse:collapse;"> <thead><tr style="color:var(--text-muted);font-size:13px;"><th style="width:32px;">#</th><th>Title</th><th>Artist</th><th style="width:54px;"><i class="fa-regular fa-clock"></i></th></tr></thead> <tbody> ${pl.tracks.map((t,i)=>` <tr style="cursor:pointer;" onclick="playPlaylist(${idx},${i})" onmouseover="this.style.backgroundColor='#1e1e1e';" onmouseout="this.style.backgroundColor='';"> <td>${i+1}</td> <td>${t.title}</td> <td>${t.artist}</td> <td>${Math.floor(t.duration/60)}:${(t.duration%60).toString().padStart(2,'0')}</td> </tr> `).join('')} </tbody> </table> `; } function openMadePlaylist(idx) { const pl = madeForYou[idx]; document.getElementById('mainContent').innerHTML = ` <div class="header"> <div class="header-left"> <button class="circle-btn" onclick="goHome()"><i class="fa-solid fa-chevron-left"></i></button> </div> <div class="header-right"> <i class="fa-solid fa-bell"></i> <img class="profile-img" src="https://randomuser.me/api/portraits/men/35.jpg" alt="Profile"> </div> </div> <div style="display:flex;align-items:end;gap:30px;margin:28px 0 34px 36px;"> <img src="${pl.image}" style="width:180px;height:180px;border-radius:10px;box-shadow:0 7px 24px #0006;"> <div> <div style="font-size:13px;color:var(--text-muted);margin-bottom:7px;">Playlist</div> <div style="font-size:38px;font-weight:800;margin-bottom:20px;">${pl.title}</div> <div style="color:var(--text-muted);">${pl.desc}</div> </div> </div> <div style="margin-left:36px;"> <button class="circle-btn" style="background:var(--primary);color:#fff;font-size:22px;width:52px;height:52px;" onclick="playMadePlaylist(${idx},0)"> <i class="fa-solid fa-play"></i> </button> </div> <table style="margin:36px 0 0 36px;min-width:350px;width:85%;color:var(--text);font-size:15px;border-collapse:collapse;"> <thead><tr style="color:var(--text-muted);font-size:13px;"><th style="width:32px;">#</th><th>Title</th><th>Artist</th><th style="width:54px;"><i class="fa-regular fa-clock"></i></th></tr></thead> <tbody> ${pl.tracks.map((t,i)=>` <tr style="cursor:pointer;" onclick="playMadePlaylist(${idx},${i})" onmouseover="this.style.backgroundColor='#1e1e1e';" onmouseout="this.style.backgroundColor='';"> <td>${i+1}</td> <td>${t.title}</td> <td>${t.artist}</td> <td>${Math.floor(t.duration/60)}:${(t.duration%60).toString().padStart(2,'0')}</td> </tr> `).join('')} </tbody> </table> `; } function goHome() { document.getElementById('mainContent').innerHTML = ` <div class="header"> <div class="header-left"> <button class="circle-btn" title="Back" disabled><i class="fa-solid fa-chevron-left"></i></button> <button class="circle-btn" title="Forward" disabled><i class="fa-solid fa-chevron-right"></i></button> </div> <div class="header-right"> <i class="fa-solid fa-bell"></i> <img class="profile-img" src="https://randomuser.me/api/portraits/men/35.jpg" alt="Profile"> </div> </div> <div class="welcome">Good afternoon</div> <div class="playlist-section"> <div class="playlist-row">Your Top Mixes</div> <div class="playlist-grid" id="playlistGrid"></div> <div class="playlist-row" style="margin-top:44px;">Made For You</div> <div class="playlist-grid" id="madeGrid"></div> </div> `; renderPlaylists(); } // "Audio player" logic, track state let currentPlaylist = null; let currentTrackIdx = 0; let madeActive = false; let audio = document.getElementById('audioPlayer'); let playing = false; // Setup player with a track function loadTrack(track) { document.querySelector('#playerSong img').src = track.image; document.querySelector('.player-song-title').textContent = track.title; document.querySelector('.player-song-artist').textContent = track.artist; document.getElementById('audioPlayer').src = track.src; document.getElementById('totalTime').textContent = formatTime(track.duration || 200); } // Play a playlist track function playPlaylist(plIdx, tIdx) { madeActive = false; currentPlaylist = {plIdx, tIdx}; currentTrackIdx = tIdx; loadTrack(playlists[plIdx].tracks[tIdx]); playAudio(); } function playMadePlaylist(plIdx,tIdx){ madeActive = true; currentPlaylist = {plIdx, tIdx}; currentTrackIdx = tIdx; loadTrack(madeForYou[plIdx].tracks[tIdx]); playAudio(); } // Audio UI controls function playAudio() { let btn = document.getElementById('playPauseBtn'); audio.play().then(()=>{}).catch(()=>{}); btn.classList.add('fa-pause'); btn.classList.remove('fa-play'); playing = true; } function pauseAudio() { let btn = document.getElementById('playPauseBtn'); audio.pause(); btn.classList.remove('fa-pause'); btn.classList.add('fa-play'); playing = false; } document.getElementById('playPauseBtn').addEventListener('click',()=>{ if(audio.src) { if(playing) pauseAudio(); else playAudio(); } }); // On song end: next track or stop audio.addEventListener('ended', ()=>{ nextTrack(); }); function nextTrack() { if(currentPlaylist) { let srcArr = madeActive ? madeForYou[currentPlaylist.plIdx].tracks : playlists[currentPlaylist.plIdx].tracks; let n = srcArr.length; currentTrackIdx = (currentTrackIdx+1)%n; loadTrack(srcArr[currentTrackIdx]); audio.play(); } } function prevTrack() { if(currentPlaylist) { let srcArr = madeActive ? madeForYou[currentPlaylist.plIdx].tracks : playlists[currentPlaylist.plIdx].tracks; let n = srcArr.length; currentTrackIdx = (currentTrackIdx-1+n)%n; loadTrack(srcArr[currentTrackIdx]); audio.play(); } } document.getElementById('nextBtn').addEventListener('click',nextTrack); document.getElementById('prevBtn').addEventListener('click',prevTrack); // Initial song loadTrack(playlists[0].tracks[0]); // Progress UI function formatTime(t){ t = Math.round(isNaN(t)?0:t); const min = Math.floor(t/60), sec = t%60; return min+':'+sec.toString().padStart(2,'0'); } audio.addEventListener('timeupdate', ()=>{ document.getElementById('curTime').textContent = formatTime(audio.currentTime); let duration = audio.duration || playlists[0].tracks[0].duration; let pct = Math.min(100, ((audio.currentTime || 0) / (duration || 1) )*100); document.getElementById('progressFill').style.width = pct + "%"; }); // Seek logic document.getElementById('progressBar').addEventListener('click',function(e){ let rect = this.getBoundingClientRect(); let x = e.clientX - rect.left; let pct = x/rect.width; if(audio.src && !isNaN(audio.duration)) { audio.currentTime = pct * audio.duration; } }); // Volume UI let volume = 0.7; audio.volume = volume; document.getElementById('volumeFilled').style.width = (volume*100)+'%'; document.getElementById('volumeBar').addEventListener('click',function(e){ let rect = this.getBoundingClientRect(); let x = e.clientX - rect.left; let pct = Math.min(1, Math.max(0, x/rect.width)); audio.volume = pct; document.getElementById('volumeFilled').style.width = (pct*100)+'%'; }); // Add playlist document.getElementById('createPlaylist').addEventListener('click',()=>{ let name = prompt('New playlist name?'); if(!name) return; playlists.push({ title: name, desc: "A personal playlist", image: "https://i.scdn.co/image/ab67706f0000000281ea150442b43b2781db96be", tracks: [] }); renderPlaylists(); }); // Sidebar nav (just dummy highlight for UI) document.querySelectorAll('.side-nav li').forEach((li,idx,arr)=>{ li.addEventListener('click', ()=>{ arr.forEach(l2=>l2.classList.remove('active')); li.classList.add('active'); if(idx===0) goHome(); // no-op for others }); }); // Populate playlist at load renderPlaylists(); // Expose functions to global window.openPlaylist = openPlaylist; window.openMadePlaylist = openMadePlaylist; window.goHome = goHome; window.playPlaylist = playPlaylist; window.playMadePlaylist = playMadePlaylist; </script> </body> </html> ``` **Features:** - Left sidebar + playlist list - Main area with header, recommended playlists - Clicking a playlist opens a track list like Spotify - Player bar: play/pause/seek/next/prev, see song info/album art, volume control - Responsive layout - No backend, uses dummy (royalty-free) mp3 files to demonstrate audio playback - Keyboard navigation and advanced features are omitted for brevity You can freely edit/expand this further.
Drag to resize
Here's a simplified Spotify clone using HTML, CSS, and JavaScript. This includes the main UI elements like the sidebar, main content area, and player controls: ```html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Spotify Clone</title> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> <style> * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; } body { display: flex; flex-direction: column; height: 100vh; background-color: #121212; color: white; } .app-container { display: flex; flex: 1; overflow: hidden; } /* Sidebar */ .sidebar { width: 240px; background-color: #000; padding: 24px; display: flex; flex-direction: column; } .logo { margin-bottom: 24px; } .logo img { height: 40px; } .nav-links { flex: 1; } .nav-item { display: flex; align-items: center; padding: 8px 0; color: #b3b3b3; font-weight: 600; font-size: 14px; cursor: pointer; } .nav-item:hover { color: white; } .nav-item i { margin-right: 16px; font-size: 20px; } .playlists { margin-top: 24px; } .playlists-title { color: #b3b3b3; font-size: 12px; font-weight: 700; text-transform: uppercase; margin-bottom: 16px; } .playlist-item { color: #b3b3b3; font-size: 14px; margin-bottom: 12px; cursor: pointer; } .playlist-item:hover { color: white; } /* Main content */ .main-content { flex: 1; overflow-y: auto; padding: 16px 24px; background: linear-gradient(#2d2d2d, #121212); } .greeting { font-size: 32px; font-weight: 700; margin-bottom: 24px; } .cards-container { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 24px; margin-bottom: 32px; } .card { background: #181818; padding: 16px; border-radius: 6px; transition: background-color 0.3s; cursor: pointer; } .card:hover { background: #282828; } .card-img { width: 100%; aspect-ratio: 1; margin-bottom: 16px; box-shadow: 0 8px 24px rgba(0, 0, 0, 0.5); } .card-title { font-weight: 700; margin-bottom: 8px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .card-description { color: #b3b3b3; font-size: 14px; line-height: 1.5; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; } /* Player */ .player { height: 80px; background-color: #181818; border-top: 1px solid #282828; display: flex; padding: 0 16px; align-items: center; } .player-controls { flex: 1; display: flex; flex-direction: column; align-items: center; } .player-buttons { display: flex; align-items: center; margin-bottom: 8px; } .player-button { background: none; border: none; color: white; font-size: 16px; margin: 0 8px; cursor: pointer; } .player-button.play { background: white; color: black; width: 32px; height: 32px; border-radius: 50%; display: flex; align-items: center; justify-content: center; } .progress-bar { width: 100%; max-width: 500px; height: 4px; background: #4d4d4d; border-radius: 2px; cursor: pointer; } .progress { height: 100%; background: white; border-radius: 2px; width: 30%; position: relative; } .progress::after { content: ''; position: absolute; right: -6px; top: -4px; width: 12px; height: 12px; background: white; border-radius: 50%; opacity: 0; transition: opacity 0.2s; } .progress-bar:hover .progress::after { opacity: 1; } .now-playing { width: 25%; display: flex; align-items: center; } .now-playing-img { width: 56px; height: 56px; margin-right: 12px; } .song-info { display: flex; flex-direction: column; } .song-title { font-size: 14px; font-weight: 600; margin-bottom: 4px; } .song-artist { font-size: 12px; color: #b3b3b3; } .player-extra { width: 25%; display: flex; justify-content: flex-end; align-items: center; } .volume-control { display: flex; align-items: center; } .volume-icon { margin-right: 8px; color: #b3b3b3; } .volume-bar { width: 100px; height: 4px; background: #4d4d4d; border-radius: 2px; cursor: pointer; } .volume-progress { height: 100%; background: white; border-radius: 2px; width: 70%; } </style> </head> <body> <div class="app-container"> <!-- Sidebar --> <div class="sidebar"> <div class="logo"> <img src="https://storage.googleapis.com/pr-newsroom-wp/1/2018/11/Spotify_Logo_RGB_White.png" alt="Spotify"> </div> <div class="nav-links"> <div class="nav-item"> <i class="fas fa-home"></i> <span>Home</span> </div> <div class="nav-item"> <i class="fas fa-search"></i> <span>Search</span> </div> <div class="nav-item"> <i class="fas fa-book"></i> <span>Your Library</span> </div> </div> <div class="playlists"> <div class="playlists-title">Playlists</div> <div class="playlist-item">Liked Songs</div> <div class="playlist-item">Recently Played</div> <div class="playlist-item">Discover Weekly</div> <div class="playlist-item">Release Radar</div> </div> </div> <!-- Main Content --> <div class="main-content"> <div class="greeting">Good afternoon</div> <div class="cards-container"> <div class="card"> <img class="card-img" src="https://i.scdn.co/image/ab67706f00000002ca5a7517a1f1c99e2a1d39e8" alt="Album"> <div class="card-title">Today's Top Hits</div> <div class="card-description">The most popular songs right now</div> </div> <div class="card"> <img class="card-img" src="https://i.scdn.co/image/ab67706f00000002ca5a7517a1f1c99e2a1d39e8" alt="Album"> <div class="card-title">RapCaviar</div> <div class="card-description">New music from Drake, Kendrick Lamar and more</div> </div> <div class="card"> <img class="card-img" src="https://i.scdn.co/image/ab67706f00000002ca5a7517a1f1c99e2a1d39e8" alt="Album"> <div class="card-title">All Out 2010s</div> <div class="card-description">The biggest songs of the 2010s</div> </div> <div class="card"> <img class="card-img" src="https://i.scdn.co/image/ab67706f00000002ca5a7517a1f1c99e2a1d39e8" alt="Album"> <div class="card-title">Rock Classics</div> <div class="card-description">Rock legends & epic songs</div> </div> <div class="card"> <img class="card-img" src="https://i.scdn.co/image/ab67706f00000002ca5a7517a1f1c99e2a1d39e8" alt="Album"> <div class="card-title">Chill Hits</div> <div class="card-description">Kick back to the best new and recent chill hits</div> </div> <div class="card"> <img class="card-img" src="https://i.scdn.co/image/ab67706f00000002ca5a7517a1f1c99e2a1d39e8" alt="Album"> <div class="card-title">Mood Booster</div> <div class="card-description">Get happy with today's dose of feel-good songs</div> </div> </div> </div> </div> <!-- Player --> <div class="player"> <div class="now-playing"> <img class="now-playing-img" src="https://i.scdn.co/image/ab67616d00001e02ff9ca10b55ce82ae553c8228" alt="Now Playing"> <div class="song-info"> <div class="song-title">Blinding Lights</div> <div class="song-artist">The Weeknd</div> </div> </div> <div class="player-controls"> <div class="player-buttons"> <button class="player-button"><i class="fas fa-random"></i></button> <button class="player-button"><i class="fas fa-step-backward"></i></button> <button class="player-button play"><i class="fas fa-pause"></i></button> <button class="player-button"><i class="fas fa-step-forward"></i></button> <button class="player-button"><i class="fas fa-redo"></i></button> </div> <div class="progress-bar"> <div class="progress"></div> </div> </div> <div class="player-extra"> <div class="volume-control"> <i class="fas fa-volume-up volume-icon"></i> <div class="volume-bar"> <div class="volume-progress"></div> </div> </div> </div> </div> <script> // Simple functionality for demonstration document.addEventListener('DOMContentLoaded', function() { // Card hover effect const cards = document.querySelectorAll('.card'); cards.forEach(card => { card.addEventListener('mouseenter', function() { this.style.transform = 'scale(1.05)'; }); card.addEventListener('mouseleave', function() { this.style.transform = 'scale(1)'; }); }); // Play button toggle const playButton = document.querySelector('.player-button.play'); playButton.addEventListener('click', function() { const icon = this.querySelector('i'); if (icon.classList.contains('fa-pause')) { icon.classList.remove('fa-pause'); icon.classList.add('fa-play'); } else { icon.classList.remove('fa-play'); icon.classList.add('fa-pause'); } }); // Progress bar click const progressBar = document.querySelector('.progress-bar'); progressBar.addEventListener('click', function(e) { const percent = e.offsetX / this.offsetWidth; this.querySelector('.progress').style.width = `${percent * 100}%`; }); // Volume bar click const volumeBar = document.querySelector('.volume-bar'); volumeBar.addEventListener('click', function(e) { const percent = e.offsetX / this.offsetWidth; this.querySelector('.volume-progress').style.width = `${percent * 100}%`; }); }); </script> </body> </html> ``` This code creates a Spotify-like interface with: 1. A dark-themed sidebar with navigation links and playlists 2. A main content area showing greeting and album cards 3. A player control bar at the bottom with: - Current track info - Playback controls (play/pause, skip, shuffle, repeat) - Progress bar - Volume control The UI includes hover effects and basic interactive elements. For a complete Spotify clone, you would need to: - Add more sophisticated JavaScript for actual music playback - Connect to the Spotify API for real data - Implement user authentication - Add more UI elements like search functionality and detailed playlist views Would you like me to enhance any specific part of this implementation?
Drag to resize
Below is a fully-contained, single-file prototype that demonstrates the core layout and behavior of a modern music-streaming interface (sidebar navigation, track list, and a bottom player bar). It does NOT use any Spotify artwork, fonts, or proprietary code—everything is built from scratch with free CDNs and a handful of royalty-free audio samples. Save the code to e.g. `index.html` and open it in any modern browser. ```html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Simple Music-Streaming UI Prototype</title> <!-- Google Fonts & Font Awesome (icons) --> <link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;600&display=swap" rel="stylesheet"> <link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css" rel="stylesheet"> <style> /* -------- VARIABLES -------- */ :root{ --bg-dark:#121212; --bg-light:#181818; --primary:#1db954; --text-light:#b3b3b3; --text-bright:#fff; } /* -------- RESET -------- */ *,*::before,*::after{box-sizing:border-box;margin:0;padding:0;} html,body{height:100%;width:100%;font-family:'Inter',sans-serif;} /* -------- LAYOUT -------- */ body{ background:var(--bg-dark); color:var(--text-light); display:flex; flex-direction:column; } #app{ flex:1; display:flex; overflow:hidden; } aside{ width:240px; background:var(--bg-light); padding:24px 16px; display:flex; flex-direction:column; gap:32px; overflow-y:auto; } main{ flex:1; overflow-y:auto; } section{ padding:24px 32px 120px; /* bottom padding keeps list clear of player bar */ } .player-bar{ height:96px; background:var(--bg-light); border-top:1px solid #000; display:flex; align-items:center; justify-content:space-between; padding:0 24px; gap:24px; color:var(--text-bright); } .player-bar .controls{display:flex;align-items:center;gap:16px;font-size:22px;} .player-bar .progress{flex:1;height:4px;background:#333;position:relative;cursor:pointer;} .player-bar .progress-inner{height:100%;background:var(--primary);width:0%;} .player-bar .meta{display:flex;flex-direction:column;gap:4px;} /* -------- COMPONENTS -------- */ .logo{ font-size:22px; font-weight:600; color:var(--text-bright); } nav ul{list-style:none;display:flex;flex-direction:column;gap:16px;font-size:14px;} nav li{cursor:pointer;transition:.2s;color:var(--text-light);} nav li.selected,nav li:hover{color:var(--text-bright);} .playlist li{cursor:pointer;padding:8px;border-radius:4px;transition:.2s;} .playlist li:hover{background:#282828;} .playlist li.active{background:#282828;color:var(--primary);} .track-title{font-size:15px;color:var(--text-bright);} .track-artist{font-size:13px;color:var(--text-light);} ::-webkit-scrollbar{width:8px;} ::-webkit-scrollbar-thumb{background:#2e2e2e;border-radius:4px;} ::-webkit-scrollbar-track{background:transparent;} </style> </head> <body> <div id="app"> <!-- ---------- SIDEBAR ---------- --> <aside> <div class="logo">MyMusic</div> <nav> <ul> <li class="selected"><i class="fa-solid fa-house"></i> Home</li> <li><i class="fa-solid fa-magnifying-glass"></i> Search</li> <li><i class="fa-solid fa-lines-leaning"></i> Library</li> </ul> </nav> <div> <h4 style="margin-bottom:8px;color:var(--text-bright);font-size:14px;">Playlists</h4> <ul id="playlistList" class="playlist"></ul> </div> </aside> <!-- ---------- MAIN CONTENT ---------- --> <main> <section> <h2 style="color:var(--text-bright);margin-bottom:16px;">Songs</h2> <ul id="trackList" class="playlist"></ul> </section> </main> </div> <!-- ---------- PLAYER BAR ---------- --> <footer class="player-bar"> <div class="meta"> <div id="metaTitle" class="track-title">Nothing playing</div> <div id="metaArtist" class="track-artist"></div> </div> <div class="controls"> <i id="prevBtn" class="fa-solid fa-backward-step"></i> <i id="playPauseBtn" class="fa-solid fa-play fa-lg"></i> <i id="nextBtn" class="fa-solid fa-forward-step"></i> </div> <div class="progress" id="progressBar"> <div class="progress-inner" id="progressFill"></div> </div> </footer> <!-- ---------- SCRIPTS ---------- --> <script> /* ------- SIMPLE DATA ------- */ const tracks = [ {title:"Summer Breeze",artist:"SoundHelix",url:"https://www.soundhelix.com/examples/mp3/SoundHelix-Song-1.mp3"}, {title:"Ocean Avenue",artist:"SoundHelix",url:"https://www.soundhelix.com/examples/mp3/SoundHelix-Song-2.mp3"}, {title:"Midnight Drive",artist:"SoundHelix",url:"https://www.soundhelix.com/examples/mp3/SoundHelix-Song-3.mp3"}, {title:"City Lights",artist:"SoundHelix",url:"https://www.soundhelix.com/examples/mp3/SoundHelix-Song-4.mp3"}, {title:"Lo-Fi Dreams",artist:"SoundHelix",url:"https://www.soundhelix.com/examples/mp3/SoundHelix-Song-5.mp3"} ]; const playlists = [ {name:"Top Picks",trackIndexes:[0,1,2]}, {name:"Chill Hits",trackIndexes:[2,3,4]}, {name:"Focus",trackIndexes:[1,4]}, ]; /* ------- UI HOOKS ------- */ const playlistListEl = document.getElementById("playlistList"); const trackListEl = document.getElementById("trackList"); const metaTitle = document.getElementById("metaTitle"); const metaArtist = document.getElementById("metaArtist"); const progressBar = document.getElementById("progressBar"); const progressFill = document.getElementById("progressFill"); const playPauseBtn = document.getElementById("playPauseBtn"); const prevBtn = document.getElementById("prevBtn"); const nextBtn = document.getElementById("nextBtn"); /* ------- AUDIO ELEMENT ------- */ const audio = new Audio(); let currentTrackIndex = -1; let currentPlaylist = tracks.map((_,i)=>i); // default: all tracks /* ------- RENDER HELPERS ------- */ function renderPlaylists(){ playlistListEl.innerHTML = ''; playlists.forEach((pl,i)=>{ const li=document.createElement('li'); li.textContent=pl.name; li.addEventListener('click',()=>{selectPlaylist(i);}); playlistListEl.appendChild(li); }); } function renderTrackList(){ trackListEl.innerHTML=''; currentPlaylist.forEach((trackIndex,i)=>{ const t=tracks[trackIndex]; const li=document.createElement('li'); li.innerHTML = ` <div class="track-title">${t.title}</div> <div class="track-artist">${t.artist}</div> `; li.addEventListener('click',()=>{playTrackAt(i);}); trackListEl.appendChild(li); }); updateActiveTrackStyling(); } function updateActiveTrackStyling(){ trackListEl.querySelectorAll('li').forEach((li,idx)=>{ li.classList.toggle('active',idx===currentTrackIndex); }); } /* ------- PLAYBACK CONTROLS ------- */ function playTrackAt(indexInPlaylist){ const globalIndex=currentPlaylist[indexInPlaylist]; const track=tracks[globalIndex]; audio.src=track.url; audio.play(); currentTrackIndex=indexInPlaylist; metaTitle.textContent=track.title; metaArtist.textContent=track.artist; playPauseBtn.classList.replace('fa-play','fa-pause'); updateActiveTrackStyling(); } function nextTrack(){ if(currentTrackIndex<currentPlaylist.length-1){ playTrackAt(currentTrackIndex+1); } } function prevTrack(){ if(currentTrackIndex>0){ playTrackAt(currentTrackIndex-1); } } /* ------- EVENTS ------- */ playPauseBtn.addEventListener('click',()=>{ if(audio.paused){ if(currentTrackIndex===-1) playTrackAt(0); else{ audio.play(); playPauseBtn.classList.replace('fa-play','fa-pause');} }else{ audio.pause(); playPauseBtn.classList.replace('fa-pause','fa-play'); } }); nextBtn.addEventListener('click',nextTrack); prevBtn.addEventListener('click',prevTrack); audio.addEventListener('timeupdate',()=>{ const p = (audio.currentTime / audio.duration)*100; progressFill.style.width = (p||0)+'%'; }); audio.addEventListener('ended',nextTrack); progressBar.addEventListener('click',e=>{ if(!audio.duration) return; const rect=progressBar.getBoundingClientRect(); const pct=(e.clientX-rect.left)/rect.width; audio.currentTime=pct*audio.duration; }); /* ------- PLAYLIST SELECTION ------- */ function selectPlaylist(idx){ currentPlaylist=playlists[idx].trackIndexes; currentTrackIndex=-1; audio.pause(); playPauseBtn.classList.replace('fa-pause','fa-play'); metaTitle.textContent='Nothing playing'; metaArtist.textContent=''; renderTrackList(); } /* ------- INIT ------- */ renderPlaylists(); renderTrackList(); </script> </body> </html> ``` What it includes: 1. A dark theme/layout reminiscent of popular streaming services. 2. Sidebar with navigation & playlist list. 3. Scrollable main area rendering all songs in the selected playlist. 4. Bottom player bar with Play/Pause, Next, Previous, seek bar, and live metadata. 5. Completely client-side JavaScript (no build tools required). All state is stored in simple arrays; swap in your own tracks or plug in an actual API as you scale. From here you can: • Replace the `tracks` array with your own audio URLs or connect to a backend/graphQL service. • Add authentication, search, queue management, etc. • Move the code into a React/Vue/Angular project for componentization.
Drag to resize
Here's a simplified Spotify UI clone focused on core layout and interactivity: ```html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Spotify Clone</title> <link href="https://cdn.jsdelivr.net/npm/tailwindcss@2.2.19/dist/tailwind.min.css" rel="stylesheet"> <link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css" rel="stylesheet"> <style> body { font-family: 'Helvetica Neue', sans-serif } .active-link { color: #1db954; border-left: 3px solid #1db954 } .album-art:hover { transform: scale(1.03); transition: 0.2s } .range-slider::-webkit-slider-thumb { background: #1db954 } </style> </head> <body class="bg-black text-white h-screen flex flex-col"> <!-- Top Bar --> <div class="bg-zinc-900 flex justify-between p-4 items-center"> <div class="text-2xl font-bold">preview</div> <div class="hidden md:flex items-center space-x-4"> <button class="hover:text-green-400"><i class="fas fa-bell"></i></button> <div class="flex items-center space-x-1"> <img src="https://i.scdn.co/image/ab67616d0000b273f7db43292a6a99b21f31a35e" class="w-8 h-8 rounded-full"> <span class="text-sm">Visitor</span> </div> </div> </div> <!-- Main Content --> <div class="flex flex-1 overflow-hidden"> <!-- Left Sidebar --> <div class="bg-zinc-900 w-60 p-5 space-y-3 hidden md:block"> <div class="px-3 py-2 rounded hover:bg-zinc-800 cursor-pointer active-link"> <i class="fas fa-home mr-3"></i> Home </div> <div class="px-3 py-2 rounded hover:bg-zinc-800 cursor-pointer"> <i class="fas fa-search mr-3"></i> Search </div> <div class="px-3 py-2 rounded hover:bg-zinc-800 cursor-pointer"> <i class="fas fa-bookmark mr-3"></i> Playlists </div> <hr class="border-zinc-800 my-3"> <div class="space-y-2"> <div class="flex items-center space-x-3 p-2 rounded hover:bg-zinc-800 cursor-pointer"> <i class="fas fa-music text-green-500 text-sm"></i> <span class="text-sm">Genre 1</span> </div> <div class="flex items-center space-x-3 p-2 rounded hover:bg-zinc-800 cursor-pointer"> <i class="fas fa-music text-green-500 text-sm"></i> <span class="text-sm">Genre 2</span> </div> </div> </div> <!-- Library Content --> <div class="flex-1 p-8 overflow-y-auto"> <h1 class="text-3xl font-bold mb-6">My Library</h1> <div class="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-6"> <!-- Album Card --> <div class="album-art bg-zinc-800 rounded overflow-hidden hover:bg-green-900 cursor-pointer" onclick="playTrack('https://www.bensound.com/bensound-music/bensound-happyrock.mp3', 'Happy Rock')"> <img src="https://i.scdn.co/image/ab67616d00001e02fghijk10293847happyrock" class="w-full h-48 object-cover"> <div class="p-4"> <h3 class="font-semibold mb-1">Happy Rock</h3> <p class="text-sm text-zinc-400">Artist: John Doe</p> </div> </div> <!-- Add more albums as needed --> <div class="album-art bg-zinc-800 rounded overflow-hidden hover:bg-green-900 cursor-pointer" onclick="playTrack('https://www.bensound.com/bensound-music/bensound-cute.mp3', 'Cute')"> <img src="https://i.scdn.co/image/ab67616d00001e03fghijk10293847cute" class="w-full h-48 object-cover"> <div class="p-4"> <h3 class="font-semibold mb-1">Cute</h3> <p class="text-sm text-zinc-400">Artist: Jane Smith</p> </div> </div> </div> </div> </div> <!-- Music Player --> <div class="bg-zinc-900 py-3 px-4 flex items-center justify-between"> <div class="flex items-center space-x-3 w-1/4"> <img id="player-art" src="https://via.placeholder.com/50" class="w-12 h-12 rounded"> <div> <div class="text-sm font-semibold" id="song-title">Select a song</div> <div class="text-xs text-zinc-400">-</div> </div> </div> <div class="flex flex-col items-center w-1/2"> <div class="flex items-center space-x-4 my-2"> <button onclick="audioPlayer.previous()" class="hover:text-green-400"> <i class="fas fa-backward"></i> </button> <button onclick="togglePlay()" id="play-btn" class="bg-green-500 p-2 rounded-full text-black hover:bg-green-400"> <i id="play-icon" class="fas fa-play"></i> </button> <button onclick="audioPlayer.next()" class="hover:text-green-400"> <i class="fas fa-forward"></i> </button> </div> <input type="range" min="0" max="100" value="0" class="range-slider w-3/4" onchange="audioPlayer.seek(this.value)"> <div class="flex justify-between text-xs text-zinc-400 w-3/4"> <span id="currentTime">0:00</span> <span id="duration">0:00</span> </div> </div> <div class="w-1/4 flex justify-end items-center space-x-3"> <button class="hover:text-green-400"> <i class="fas fa-heart"></i> </button> <input type="range" min="0" max="1" step="0.01" value="0.7" class="range-slider" onchange="audioPlayer.setVolume(this.value)"> </div> </div> <!-- Audio Element --> <audio id="audio" src=""></audio> <script> const audio = document.getElementById('audio'); const playBtn = document.getElementById('play-btn'); const playIcon = document.getElementById('play-icon'); const songTitle = document.getElementById('song-title'); const playerArt = document.getElementById('player-art'); const currentTime = document.getElementById('currentTime'); const duration = document.getElementById('duration'); let queue = []; let currentTrack = 0; function formatTime(seconds) { const mins = Math.floor(seconds / 60).toString().padStart(2, '0'); const secs = Math.floor(seconds % 60).toString().padStart(2, '0'); return `${mins}:${secs}`; } const audioPlayer = { play(url, title) { audio.src = url; songTitle.textContent = title; playerArt.src = url.replace('mp3', 'png').replace('music/', 'album/'); audio.play(); playIcon.className = 'fas fa-pause'; }, toggle() { if (audio.paused) { audio.play(); playIcon.className = 'fas fa-pause'; } else { audio.pause(); playIcon.className = 'fas fa-play'; } }, seek(value) { audio.currentTime = audio.duration * (value / 100); }, setVolume(value) { audio.volume = value; }, next() { // Implement queue logic here if needed if (audio.ended) audio.currentTime = 0; audio.play(); }, previous() { audio.currentTime = 0; audio.play(); } }; audio.addEventListener('timeupdate', () => { currentTime.textContent = formatTime(audio.currentTime); duration.textContent = formatTime(audio.duration); if (audio.duration) { const progress = (audio.currentTime / audio.duration) * 100; document.querySelector('.range-slider').value = progress; } }); function togglePlay() { audioPlayer.toggle(); } function playTrack(url, title) { audioPlayer.play(url, title); } </script> </body> </html> ``` Key features included: 1. Spotify-style dark interface with green accents 2. Responsive layout that works on mobile and desktop 3. Navigation sidebar with hover effects 4. Album grid system with interactive cards 5. Functional music player with: - Play/Pause toggle - Seek control - Volume control - Current time/duration display - Previous/Next track buttons 6. Sample music tracks from Bensound (public domain) 7. Track artwork that updates dynamically 8. Basic queue functionality Note: This is a frontend-only implementation that uses: - Tailwind CSS for styling - Font Awesome for icons - HTML5 Audio API for playback - Public domain music samples To use, simply save this code as an .html file and open in your browser. The music player will load sample tracks when you click on album cards.
Drag to resize
```html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Spotify Clone</title> <link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css" rel="stylesheet"> <style> * { margin: 0; padding: 0; box-sizing: border-box; } body { background-color: #000; color: #fff; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; overflow: hidden; } .app-container { display: grid; grid-template-areas: "sidebar main" "player player"; grid-template-columns: 240px 1fr; grid-template-rows: 1fr 90px; height: 100vh; } /* Sidebar */ .sidebar { grid-area: sidebar; background-color: #000; padding: 24px 0; display: flex; flex-direction: column; } .logo { padding: 0 24px 18px; margin-bottom: 18px; } .logo h1 { color: #fff; font-size: 24px; font-weight: 700; } .nav-menu { list-style: none; padding: 0 24px; margin-bottom: 24px; } .nav-item { margin-bottom: 16px; } .nav-link { display: flex; align-items: center; color: #b3b3b3; text-decoration: none; font-weight: 500; transition: color 0.3s; } .nav-link:hover, .nav-link.active { color: #fff; } .nav-link i { width: 24px; margin-right: 16px; font-size: 18px; } .divider { height: 1px; background-color: #282828; margin: 0 24px 24px; } .playlist-section h3 { color: #b3b3b3; font-size: 14px; padding: 0 24px; margin-bottom: 16px; text-transform: uppercase; font-weight: 700; } .playlist-list { list-style: none; padding: 0 24px; overflow-y: auto; flex: 1; } .playlist-item { margin-bottom: 12px; } .playlist-link { color: #b3b3b3; text-decoration: none; font-size: 14px; transition: color 0.3s; } .playlist-link:hover { color: #fff; } /* Main Content */ .main-content { grid-area: main; background: linear-gradient(to bottom, rgba(168, 100, 168, 0.6) 0%, rgba(0, 0, 0, 0.6) 100%), #121212; overflow-y: auto; } .top-bar { display: flex; justify-content: space-between; align-items: center; padding: 16px 32px; background: rgba(0, 0, 0, 0.1); backdrop-filter: blur(10px); } .nav-buttons { display: flex; gap: 16px; } .nav-btn { background: rgba(0, 0, 0, 0.7); border: none; color: #fff; width: 32px; height: 32px; border-radius: 50%; cursor: pointer; transition: background 0.3s; } .nav-btn:hover { background: rgba(0, 0, 0, 0.9); } .user-profile { display: flex; align-items: center; background: rgba(0, 0, 0, 0.7); padding: 2px; border-radius: 23px; cursor: pointer; } .user-avatar { width: 28px; height: 28px; border-radius: 50%; background: #1db954; display: flex; align-items: center; justify-content: center; margin-right: 8px; font-size: 12px; } .username { font-size: 14px; font-weight: 700; margin-right: 8px; } .content { padding: 32px; } .section-title { font-size: 24px; font-weight: 700; margin-bottom: 24px; } .cards-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: 24px; margin-bottom: 48px; } .card { background: #181818; padding: 16px; border-radius: 8px; cursor: pointer; transition: background 0.3s; position: relative; } .card:hover { background: #282828; } .card:hover .play-btn { opacity: 1; transform: translateY(0); } .card-image { width: 100%; aspect-ratio: 1; background: linear-gradient(135deg, #1db954, #1ed760); border-radius: 8px; margin-bottom: 16px; position: relative; display: flex; align-items: center; justify-content: center; font-size: 48px; color: rgba(0, 0, 0, 0.7); } .play-btn { position: absolute; bottom: 8px; right: 8px; width: 48px; height: 48px; background: #1db954; border-radius: 50%; border: none; color: #000; font-size: 16px; cursor: pointer; opacity: 0; transform: translateY(8px); transition: all 0.3s; display: flex; align-items: center; justify-content: center; } .card-title { font-size: 16px; font-weight: 700; margin-bottom: 4px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .card-subtitle { font-size: 14px; color: #b3b3b3; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } /* Player */ .player { grid-area: player; background: #181818; border-top: 1px solid #282828; display: flex; align-items: center; justify-content: space-between; padding: 0 16px; } .player-left, .player-right { flex: 1; display: flex; align-items: center; } .player-center { flex: 2; display: flex; flex-direction: column; align-items: center; } .now-playing { display: flex; align-items: center; } .album-cover { width: 56px; height: 56px; background: linear-gradient(135deg, #1db954, #1ed760); border-radius: 4px; margin-right: 12px; } .track-info h4 { font-size: 14px; margin-bottom: 4px; } .track-info p { font-size: 12px; color: #b3b3b3; } .player-controls { display: flex; align-items: center; gap: 16px; margin-bottom: 8px; } .control-btn { background: none; border: none; color: #b3b3b3; cursor: pointer; transition: color 0.3s; } .control-btn:hover { color: #fff; } .play-pause { width: 32px; height: 32px; background: #fff; border-radius: 50%; display: flex; align-items: center; justify-content: center; color: #000; } .progress-section { display: flex; align-items: center; gap: 12px; width: 100%; max-width: 500px; } .time { font-size: 12px; color: #b3b3b3; min-width: 40px; text-align: center; } .progress-bar { flex: 1; height: 4px; background: #4d4d4d; border-radius: 2px; cursor: pointer; position: relative; } .progress-fill { height: 100%; background: #fff; border-radius: 2px; width: 30%; position: relative; } .progress-handle { width: 12px; height: 12px; background: #fff; border-radius: 50%; position: absolute; right: -6px; top: 50%; transform: translateY(-50%); opacity: 0; transition: opacity 0.3s; } .progress-bar:hover .progress-handle { opacity: 1; } .volume-controls { display: flex; align-items: center; gap: 8px; justify-content: flex-end; } .volume-bar { width: 100px; height: 4px; background: #4d4d4d; border-radius: 2px; cursor: pointer; } .volume-fill { height: 100%; background: #fff; border-radius: 2px; width: 70%; } @media (max-width: 768px) { .app-container { grid-template-columns: 1fr; grid-template-areas: "main" "player"; } .sidebar { display: none; } } </style> </head> <body> <div class="app-container"> <!-- Sidebar --> <div class="sidebar"> <div class="logo"> <h1>Spotify</h1> </div> <ul class="nav-menu"> <li class="nav-item"> <a href="#" class="nav-link active"> <i class="fas fa-home"></i> Home </a> </li> <li class="nav-item"> <a href="#" class="nav-link"> <i class="fas fa-search"></i> Search </a> </li> <li class="nav-item"> <a href="#" class="nav-link"> <i class="fas fa-list"></i> Your Library </a> </li> </ul> <div class="divider"></div> <div class="playlist-section"> <h3>Playlists</h3> <ul class="playlist-list"> <li class="playlist-item"> <a href="#" class="playlist-link">Create Playlist</a> </li> <li class="playlist-item"> <a href="#" class="playlist-link">Liked Songs</a> </li> <li class="playlist-item"> <a href="#" class="playlist-link">Your Episodes</a> </li> <li class="playlist-item"> <a href="#" class="playlist-link">My Playlist #1</a> </li> <li class="playlist-item"> <a href="#" class="playlist-link">Chill Mix</a> </li> <li class="playlist-item"> <a href="#" class="playlist-link">Rock Classics</a> </li> <li class="playlist-item"> <a href="#" class="playlist-link">Workout Hits</a> </li> </ul> </div> </div> <!-- Main Content --> <div class="main-content"> <div class="top-bar"> <div class="nav-buttons"> <button class="nav-btn"> <i class="fas fa-chevron-left"></i> </button> <button class="nav-btn"> <i class="fas fa-chevron-right"></i> </button> </div> <div class="user-profile"> <div class="user-avatar"> <i class="fas fa-user"></i> </div> <span class="username">User</span> <i class="fas fa-chevron-down"></i> </div> </div> <div class="content"> <h2 class="section-title">Good afternoon</h2> <div class="cards-grid"> <div class="card" onclick="playTrack('Liked Songs')"> <div class="card-image"> <i class="fas fa-heart"></i> <button class="play-btn"> <i class="fas fa-play"></i> </button> </div> <div class="card-title">Liked Songs</div> <div class="card-subtitle">320 liked songs</div> </div> <div class="card" onclick="playTrack('Daily Mix 1')"> <div class="card-image"> <i class="fas fa-music"></i> <button class="play-btn"> <i class="fas fa-play"></i> </button> </div> <div class="card-title">Daily Mix 1</div> <div class="card-subtitle">Made for you</div> </div> <div class="card" onclick="playTrack('Discover Weekly')"> <div class="card-image"> <i class="fas fa-compact-disc"></i> <button class="play-btn"> <i class="fas fa-play"></i> </button> </div> <div class="card-title">Discover Weekly</div> <div class="card-subtitle">Your weekly mixtape of fresh music</div> </div> <div class="card" onclick="playTrack('Release Radar')"> <div class="card-image"> <i class="fas fa-satellite-dish"></i> <button class="play-btn"> <i class="fas fa-play"></i> </button> </div> <div class="card-title">Release Radar</div> <div class="card-subtitle">Catch all the latest music</div> </div> <div class="card" onclick="playTrack('Rock Classics')"> <div class="card-image"> <i class="fas fa-guitar"></i> <button class="play-btn"> <i class="fas fa-play"></i> </button> </div> <div class="card-title">Rock Classics</div> <div class="card-subtitle">The greatest rock hits</div> </div> <div class="card" onclick="playTrack('Chill Hits')"> <div class="card-image"> <i class="fas fa-leaf"></i> <button class="play-btn"> <i class="fas fa-play"></i> </button> </div> <div class="card-title">Chill Hits</div> <div class="card-subtitle">Kick back to the best new and recent chill hits</div> </div> </div> <h2 class="section-title">Made for you</h2> <div class="cards-grid"> <div class="card"> <div class="card-image"> <i class="fas fa-star"></i> <button class="play-btn"> <i class="fas fa-play"></i> </button> </div> <div class="card-title">Your Top Songs 2023</div> <div class="card-subtitle">Your most played songs this year</div> </div> <div class="card"> <div class="card-image"> <i class="fas fa-history"></i> <button class="play-btn"> <i class="fas fa-play"></i> </button> </div> <div class="card-title">On Repeat</div> <div class="card-subtitle">Songs you can't stop playing</div> </div> <div class="card"> <div class="card-image"> <i class="fas fa-clock"></i> <button class="play-btn"> <i class="fas fa-play"></i> </button> </div> <div class="card-title">Repeat Rewind</div> <div class="card-subtitle">Songs you loved and lost</div> </div> </div> </div> </div> <!-- Player --> <div class="player"> <div class="player-left"> <div class="now-playing"> <div class="album-cover"></div> <div class="track-info"> <h4 id="track-title">Choose a song</h4> <p id="track-artist">Artist</p> </div> </div> </div> <div class="player-center"> <div class="player-controls"> <button class="control-btn"> <i class="fas fa-random"></i> </button> <button class="control-btn"> <i class="fas fa-step-backward"></i> </button> <button class="control-btn play-pause" onclick="togglePlayPause()"> <i class="fas fa-play" id="play-icon"></i> </button> <button class="control-btn"> <i class="fas fa-step-forward"></i> </button> <button class="control-btn"> <i class="fas fa-redo"></i> </button> </div> <div class="progress-section"> <span class="time">0:00</span> <div class="progress-bar" onclick="seekTo(event)"> <div class="progress-fill"> <div class="progress-handle"></div> </div> </div> <span class="time">3:45</span> </div> </div> <div class="player-right"> <div class="volume-controls"> <button class="control-btn"> <i class="fas fa-volume-up"></i> </button> <div class="volume-bar"> <div class="volume-fill"></div> </div> </div> </div> </div> </div> <script> let isPlaying = false; let currentProgress = 0; function togglePlayPause() { const playIcon = document.getElementById('play-icon'); isPlaying = !isPlaying; if (isPlaying) { playIcon.className = 'fas fa-pause'; startProgressSimulation(); } else { playIcon.className = 'fas fa-play'; stopProgressSimulation(); } } function playTrack(trackName) { document.getElementById('track-title').textContent = trackName; document.getElementById('track-artist').textContent = 'Spotify Clone'; if (!isPlaying) { togglePlayPause(); } } let progressInterval; function startProgressSimulation() { progressInterval = setInterval(() => { currentProgress += 0.5; if (currentProgress >= 100) { currentProgress = 0; } updateProgressBar(); }, 200); } function stopProgressSimulation() { clearInterval(progressInterval); } function updateProgressBar() { const progressFill = document.querySelector('.progress-fill'); progressFill.style.width = currentProgress + '%'; const currentTime = Math.floor((currentProgress / 100) * 225); // 3:45 = 225 seconds const minutes = Math.floor(currentTime / 60); const seconds = currentTime % 60; const timeElement = document.querySelector('.time'); timeElement.textContent = `${minutes}:${seconds.toString().padStart(2, '0')}`; } function seekTo(event) { const progressBar = event.currentTarget; const rect = progressBar.getBoundingClientRect(); const clickX = event.clientX - rect.left; const width = rect.width; currentProgress = (clickX / width) * 100; updateProgressBar(); } // Simulate some interactions document.addEventListener('DOMContentLoaded', function() { // Add some hover effects and interactions const cards = document.querySelectorAll('.card'); cards.forEach(card => { card.addEventListener('mouseenter', function() { this.style.transform = 'scale(1.05)'; this.style.transition = 'transform 0.3s ease'; }); card.addEventListener('mouseleave', function() { this.style.transform = 'scale(1)'; }); }); // Add click effects to navigation const navLinks = document.querySelectorAll('.nav-link'); navLinks.forEach(link => { link.addEventListener('click', function(e) { e.preventDefault(); navLinks.forEach(l => l.classList.remove('active')); this.classList.add('active'); }); }); }); </script> </body> </html> ```
Drag to resize
Creating a clone of the Spotify web/desktop app is a complex project that involves front-end development, back-end development, API integration, and music streaming functionality. Below is a simplified version of how you might structure such a project using HTML, CSS, and JavaScript. This example will focus on the front-end and basic functionality. For a full-scale clone, you would need to handle user authentication, music playback, and API requests to a music database (like Spotify's API or a custom solution). Here’s a basic structure to get started: ```html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Spotifly - Music Streaming App</title> <link rel="stylesheet" href="styles.css"> </head> <body> <div class="app"> <!-- Sidebar --> <div class="sidebar"> <div class="logo">Spotifly</div> <nav> <ul> <li><a href="#" class="active">Home</a></li> <li><a href="#">Search</a></li> <li><a href="#">Library</a></li> </ul> </nav> <div class="playlist"> <h3>Playlists</h3> <ul> <li><a href="#">My Playlist</a></li> <li><a href="#">Discover Weekly</a></li> </ul> </div> </div> <!-- Main Content --> <div class="main-content"> <header> <div class="search-bar"> <input type="text" placeholder="Search for Artists, Songs, or Podcasts"> </div> <div class="user"> <img src="user.png" alt="User Profile" class="user-profile"> </div> </header> <div class="content"> <h1>Good Morning</h1> <div class="cards"> <div class="card">Playlist 1</div> <div class="card">Playlist 2</div> <div class="card">Playlist 3</div> </div> </div> </div> <!-- Music Player --> <div class="music-player"> <div class="song-info"> <img src="album.png" alt="Album Cover" class="album-cover"> <div class="song-details"> <h3>Song Title</h3> <p>Artist Name</p> </div> </div> <div class="controls"> <button class="play-pause">▶️</button> <input type="range" class="progress-bar" value="0"> </div> <div class="volume-control"> <button class="volume">🔊</button> <input type="range" class="volume-bar" value="50"> </div> </div> </div> <script src="app.js"></script> </body> </html> ``` ```css /* styles.css */ body, html { margin: 0; padding: 0; font-family: 'Arial', sans-serif; background-color: #121212; color: #fff; } .app { display: flex; height: 100vh; } .sidebar { width: 250px; background-color: #000; padding: 20px; } .logo { font-size: 24px; font-weight: bold; margin-bottom: 20px; } .sidebar nav ul, .playlist ul { list-style: none; padding: 0; } .sidebar nav ul li, .playlist ul li { margin: 10px 0; } .sidebar a { color: #b3b3b3; text-decoration: none; } .sidebar a.active { color: #fff; } .main-content { flex: 1; padding: 20px; background: linear-gradient(to bottom, #222, #121212); overflow-y: auto; } .search-bar input { width: 300px; padding: 10px; border-radius: 20px; border: none; background-color: #222; color: #fff; } .content { margin-top: 20px; } .cards { display: flex; gap: 20px; } .card { background-color: #333; padding: 20px; border-radius: 10px; width: 150px; text-align: center; } .music-player { position: fixed; bottom: 0; left: 0; right: 0; background-color: #222; padding: 10px; display: flex; justify-content: space-between; align-items: center; } .song-info { display: flex; align-items: center; } .album-cover { width: 50px; height: 50px; margin-right: 10px; } .controls { display: flex; align-items: center; gap: 10px; } .progress-bar, .volume-bar { width: 200px; } ``` ```javascript // app.js document.querySelector('.play-pause').addEventListener('click', function() { this.innerHTML = this.innerHTML === '▶️' ? '⏸️' : '▶️'; }); document.querySelector('.volume').addEventListener('click', function() { const volumeBar = document.querySelector('.volume-bar'); volumeBar.value = volumeBar.value === '0' ? '50' : '0'; }); ``` ### Notes: 1. **API Integration**: To fetch music, playlists, and user data, you would need to integrate with an API like Spotify's Web API or a custom backend. 2. **Music Playback**: For actual music playback, you would need to use the `<audio>` tag and handle streaming from a server or API. 3. **Authentication**: Implement OAuth 2.0 for user authentication, similar to Spotify's login system. 4. **Responsive Design**: This example is basic; a full clone would require responsive design for various screen sizes. 5. **Backend**: For a full-scale app, you’ll need a backend to handle user data, playlists, and music storage/streaming. This is a starting point and would require significant expansion for a fully functional Spotify clone.
Drag to resize
```html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Spotify Clone</title> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.1.1/css/all.min.css"> <style> body { font-family: Arial, sans-serif; margin: 0; padding: 0; background-color: #121212; color: #fff; } .container { display: flex; flex-direction: row; height: 100vh; width: 100vw; } .sidebar { background-color: #000; width: 250px; padding: 20px; display: flex; flex-direction: column; } .sidebar a { color: #b3b3b3; text-decoration: none; padding: 10px; border-radius: 5px; } .sidebar a:hover { background-color: #282828; color: #fff; } .main-content { flex-grow: 1; padding: 20px; overflow-y: auto; } .header { display: flex; justify-content: space-between; align-items: center; padding: 20px; background-color: #1a1a1a; border-bottom: 1px solid #333; } .header .nav-arrows { display: flex; align-items: center; } .header .nav-arrows button { background-color: #333; border: none; padding: 10px; margin-right: 10px; border-radius: 50%; cursor: pointer; } .header .nav-arrows button:hover { background-color: #444; } .header .user-profile { display: flex; align-items: center; } .header .user-profile img { width: 30px; height: 30px; border-radius: 50%; margin-right: 10px; } .playlist-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 20px; } .playlist-card { background-color: #282828; padding: 20px; border-radius: 10px; cursor: pointer; } .playlist-card:hover { background-color: #333; } .playlist-card img { width: 100%; height: 150px; object-fit: cover; border-radius: 10px; } .playlist-card h3 { margin-top: 10px; } .playlist-card p { color: #b3b3b3; } .now-playing-bar { position: fixed; bottom: 0; width: 100%; background-color: #1a1a1a; padding: 10px; display: flex; justify-content: space-between; align-items: center; border-top: 1px solid #333; } .now-playing-bar .song-info { display: flex; align-items: center; } .now-playing-bar .song-info img { width: 50px; height: 50px; object-fit: cover; margin-right: 10px; } .now-playing-bar .controls { display: flex; align-items: center; } .now-playing-bar .controls button { background-color: #333; border: none; padding: 10px; margin-right: 10px; border-radius: 50%; cursor: pointer; } .now-playing-bar .controls button:hover { background-color: #444; } </style> </head> <body> <div class="container"> <div class="sidebar"> <a href="#"><i class="fa-solid fa-house"></i> Home</a> <a href="#"><i class="fa-solid fa-magnifying-glass"></i> Search</a> <a href="#"><i class="fa-solid fa-bookmark"></i> Your Library</a> <hr> <a href="#"><i class="fa-solid fa-plus"></i> Create Playlist</a> <a href="#"><i class="fa-solid fa-heart"></i> Liked Songs</a> </div> <div class="main-content"> <div class="header"> <div class="nav-arrows"> <button><i class="fa-solid fa-chevron-left"></i></button> <button><i class="fa-solid fa-chevron-right"></i></button> </div> <div class="user-profile"> <img src="https://via.placeholder.com/30" alt="User Profile Picture"> <span>User Name</span> </div> </div> <h2>Playlists</h2> <div class="playlist-grid"> <div class="playlist-card"> <img src="https://via.placeholder.com/150" alt="Playlist Image"> <h3>Playlist 1</h3> <p>Playlist description</p> </div> <div class="playlist-card"> <img src="https://via.placeholder.com/150" alt="Playlist Image"> <h3>Playlist 2</h3> <p>Playlist description</p> </div> <div class="playlist-card"> <img src="https://via.placeholder.com/150" alt="Playlist Image"> <h3>Playlist 3</h3> <p>Playlist description</p> </div> </div> </div> </div> <div class="now-playing-bar"> <div class="song-info"> <img src="https://via.placeholder.com/50" alt="Song Image"> <span>Song Name - Artist</span> </div> <div class="controls"> <button><i class="fa-solid fa-backward-step"></i></button> <button><i class="fa-solid fa-play"></i></button> <button><i class="fa-solid fa-forward-step"></i></button> </div> <div class="volume-control"> <input type="range" min="0" max="100" value="50"> </div> </div> </body> </html> ``` This HTML code creates a basic Spotify web app clone. The layout is divided into a sidebar and main content area. The sidebar contains navigation links, and the main content area displays a header with navigation arrows and user profile information, followed by a grid of playlist cards. The now-playing bar at the bottom displays the currently playing song and provides controls for playback. To enhance this basic structure, you can add CSS for styling and JavaScript for interactivity. You can also integrate a backend service to fetch real data from Spotify's API. **Example Use Cases:** 1. User clicks on a playlist card to view its details. 2. User interacts with the now-playing bar to control playback. 3. User navigates through different sections using the sidebar links. **Future Improvements:** 1. Integrate Spotify's API to fetch user data and playlists. 2. Implement playback functionality using HTML5 audio or a library like Howler.js. 3. Enhance the UI with more detailed playlist information and animations. 4. Add user authentication to access personalized data. **Step-by-Step Solution:** 1. Create a new HTML file and copy the provided code into it. 2. Open the file in a web browser to view the basic Spotify clone. 3. Enhance the UI and add interactivity using CSS and JavaScript. 4. Integrate Spotify's API to fetch real data and implement playback functionality. 5. Test and refine the application for a seamless user experience.
Drag to resize