• 25 Jul, 2025

How to Create a Music Player App Using HTML, CSS, and JavaScript

How to Create a Music Player App Using HTML, CSS, and JavaScript

Follow this detailed step-by-step guide to create a fully functional music player app using HTML, CSS, and JavaScript. Learn to implement play/pause controls, next/previous track navigation, progress bar seeking, volume adjustment, shuffle & repeat modes, interactive queue, and responsive design for all devices.

Music is a universal language that connects us all. Building a custom music player app is a fantastic way to practice front-end web development and create something both functional and fun. In this tutorial, we'll walk you through building a Music Player App with essential features:

  • Play/Pause Controls
  • Next/Previous Track navigation
  • Progress Bar with seeking
  • Volume Control slider
  • Shuffle & Repeat toggles
  • Interactive Queue display
  • Responsive Design for all screen sizes

Let’s dive in!


Step 1: Set Up Your HTML Structure

We'll start with the basic markup that houses the player controls, progress bar, volume slider, and track list.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Music Player</title>
    <link rel="stylesheet" href="styles.css">
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
</head>
<body>
    <div class="music-player">
        <div class="player-header">
            <h1>Music Player</h1>
            <div class="player-controls-top">
                <button id="shuffle-btn" class="control-btn" title="Shuffle">
                    <i class="fas fa-random"></i>
                </button>
                <button id="repeat-btn" class="control-btn" title="Repeat">
                    <i class="fas fa-redo"></i>
                </button>
            </div>
        </div>
        
        <div class="album-art">
            <img id="album-art" src="https://via.placeholder.com/300" alt="Album Art">
        </div>
        
        <div class="song-info">
            <h2 id="song-title">Song Title</h2>
            <p id="artist-name">Artist Name</p>
        </div>
        
        <div class="progress-container">
            <span id="current-time">0:00</span>
            <input type="range" id="progress-bar" value="0">
            <span id="duration">0:00</span>
        </div>
        
        <div class="player-controls">
            <button id="prev-btn" class="control-btn" title="Previous">
                <i class="fas fa-step-backward"></i>
            </button>
            <button id="play-btn" class="control-btn play-pause" title="Play">
                <i class="fas fa-play"></i>
            </button>
            <button id="next-btn" class="control-btn" title="Next">
                <i class="fas fa-step-forward"></i>
            </button>
        </div>
        
        <div class="volume-control">
            <i class="fas fa-volume-down"></i>
            <input type="range" id="volume-slider" min="0" max="1" step="0.01" value="0.7">
            <i class="fas fa-volume-up"></i>
        </div>
        
        <div class="queue-container">
            <h3>Up Next</h3>
            <ul id="song-queue">
                <!-- Songs will be added here dynamically -->
            </ul>
        </div>
    </div>

    <audio id="audio-player"></audio>
    
    <script src="script.js"></script>
</body>
</html>

Step 2: Style the Player with CSS

Let's make the player visually appealing and responsive.

:root {
    --primary-color: #4a76a8;
    --secondary-color: #f5f5f5;
    --text-color: #333;
    --highlight-color: #6ba1d8;
    --shadow-color: rgba(0, 0, 0, 0.2);
}

* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
    font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
}

body {
    background-color: var(--secondary-color);
    color: var(--text-color);
    display: flex;
    justify-content: center;
    align-items: center;
    min-height: 100vh;
    padding: 20px;
}

.music-player {
    background-color: white;
    border-radius: 15px;
    box-shadow: 0 10px 30px var(--shadow-color);
    width: 100%;
    max-width: 400px;
    padding: 25px;
    text-align: center;
}

.player-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 20px;
}

.player-header h1 {
    font-size: 1.5rem;
    color: var(--primary-color);
}

.control-btn {
    background: none;
    border: none;
    color: var(--primary-color);
    font-size: 1.2rem;
    cursor: pointer;
    padding: 8px;
    border-radius: 50%;
    transition: all 0.3s ease;
}

.control-btn:hover {
    background-color: var(--secondary-color);
    transform: scale(1.1);
}

.album-art {
    margin: 0 auto 20px;
    width: 200px;
    height: 200px;
    border-radius: 50%;
    overflow: hidden;
    box-shadow: 0 5px 15px var(--shadow-color);
    animation: rotateAlbumArt 20s linear infinite;
    animation-play-state: paused;
}

.album-art img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.music-player.playing .album-art {
    animation-play-state: running;
}

.song-info {
    margin-bottom: 20px;
}

.song-info h2 {
    font-size: 1.5rem;
    margin-bottom: 5px;
}

.song-info p {
    color: #666;
    font-size: 1rem;
}

.progress-container {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 20px;
}

.progress-container span {
    font-size: 0.8rem;
    color: #666;
    width: 40px;
}

#progress-bar {
    flex-grow: 1;
    margin: 0 10px;
    height: 6px;
    -webkit-appearance: none;
    appearance: none;
    background-color: #ddd;
    border-radius: 3px;
    cursor: pointer;
}

#progress-bar::-webkit-slider-thumb {
    -webkit-appearance: none;
    width: 15px;
    height: 15px;
    background-color: var(--primary-color);
    border-radius: 50%;
    cursor: pointer;
}

.player-controls {
    display: flex;
    justify-content: center;
    align-items: center;
    margin-bottom: 20px;
}

.play-pause {
    background-color: var(--primary-color);
    color: white;
    width: 50px;
    height: 50px;
    border-radius: 50%;
    margin: 0 20px;
    font-size: 1.5rem;
    display: flex;
    justify-content: center;
    align-items: center;
}

.play-pause:hover {
    background-color: var(--highlight-color);
    transform: scale(1.1);
}

.volume-control {
    display: flex;
    align-items: center;
    justify-content: center;
    margin-bottom: 20px;
}

.volume-control i {
    color: var(--primary-color);
    margin: 0 10px;
}

#volume-slider {
    width: 100px;
    height: 5px;
    -webkit-appearance: none;
    appearance: none;
    background-color: #ddd;
    border-radius: 3px;
    cursor: pointer;
}

#volume-slider::-webkit-slider-thumb {
    -webkit-appearance: none;
    width: 12px;
    height: 12px;
    background-color: var(--primary-color);
    border-radius: 50%;
    cursor: pointer;
}

.queue-container {
    text-align: left;
    margin-top: 20px;
    max-height: 200px;
    overflow-y: auto;
}

.queue-container h3 {
    color: var(--primary-color);
    margin-bottom: 10px;
    font-size: 1rem;
}

#song-queue {
    list-style-type: none;
}

#song-queue li {
    padding: 8px 10px;
    border-bottom: 1px solid #eee;
    cursor: pointer;
    transition: background-color 0.2s;
}

#song-queue li:hover {
    background-color: var(--secondary-color);
}

#song-queue li.playing {
    color: var(--primary-color);
    font-weight: bold;
}

.active {
    color: var(--highlight-color);
}

@keyframes rotateAlbumArt {
    0% {
        transform: rotate(0deg);
    }
    100% {
        transform: rotate(360deg);
    }
}

/* Responsive Design */
@media (max-width: 480px) {
    .music-player {
        padding: 15px;
    }
    
    .album-art {
        width: 150px;
        height: 150px;
    }
    
    .song-info h2 {
        font-size: 1.2rem;
    }
    
    .play-pause {
        width: 45px;
        height: 45px;
        margin: 0 15px;
    }
}

Step 3: Add JavaScript Functionality

Now the fun part — powering up the player with JavaScript.

document.addEventListener('DOMContentLoaded', function() {
    // DOM Elements
    const audioPlayer = document.getElementById('audio-player');
    const playBtn = document.getElementById('play-btn');
    const prevBtn = document.getElementById('prev-btn');
    const nextBtn = document.getElementById('next-btn');
    const progressBar = document.getElementById('progress-bar');
    const currentTimeEl = document.getElementById('current-time');
    const durationEl = document.getElementById('duration');
    const volumeSlider = document.getElementById('volume-slider');
    const shuffleBtn = document.getElementById('shuffle-btn');
    const repeatBtn = document.getElementById('repeat-btn');
    const songTitle = document.getElementById('song-title');
    const artistName = document.getElementById('artist-name');
    const albumArt = document.getElementById('album-art');
    const songQueue = document.getElementById('song-queue');
    const musicPlayer = document.querySelector('.music-player');
    
    // Music library
    const songs = [
        {
            title: "Blinding Lights",
            artist: "The Weeknd",
            src: "https://www.soundhelix.com/examples/mp3/SoundHelix-Song-1.mp3",
            cover: "https://i.scdn.co/image/ab67616d0000b2734718e2b124f79258be7bc452"
        },
        {
            title: "Save Your Tears",
            artist: "The Weeknd",
            src: "https://www.soundhelix.com/examples/mp3/SoundHelix-Song-2.mp3",
            cover: "https://i.scdn.co/image/ab67616d0000b2738863bc11d2aa12b54f5aeb36"
        },
        {
            title: "Starboy",
            artist: "The Weeknd ft. Daft Punk",
            src: "https://www.soundhelix.com/examples/mp3/SoundHelix-Song-3.mp3",
            cover: "https://i.scdn.co/image/ab67616d0000b2734718e2b124f79258be7bc452"
        },
        {
            title: "Take My Breath",
            artist: "The Weeknd",
            src: "https://www.soundhelix.com/examples/mp3/SoundHelix-Song-4.mp3",
            cover: "https://i.scdn.co/image/ab67616d0000b2734718e2b124f79258be7bc452"
        },
        {
            title: "Die For You",
            artist: "The Weeknd",
            src: "https://www.soundhelix.com/examples/mp3/SoundHelix-Song-5.mp3",
            cover: "https://i.scdn.co/image/ab67616d0000b2734718e2b124f79258be7bc452"
        }
    ];
    
    // Player state
    let currentSongIndex = 0;
    let isPlaying = false;
    let isShuffled = false;
    let isRepeated = false;
    let originalQueue = [...songs];
    let shuffledQueue = [];
    
    // Initialize player
    function initPlayer() {
        loadSong(currentSongIndex);
        updateQueue();
    }
    
    // Load song
    function loadSong(index) {
        const song = songs[index];
        songTitle.textContent = song.title;
        artistName.textContent = song.artist;
        albumArt.src = song.cover;
        audioPlayer.src = song.src;
        
        // Update active song in queue
        const queueItems = songQueue.querySelectorAll('li');
        queueItems.forEach(item => item.classList.remove('playing'));
        queueItems[index].classList.add('playing');
    }
    
    // Play song
    function playSong() {
        isPlaying = true;
        musicPlayer.classList.add('playing');
        playBtn.innerHTML = '<i class="fas fa-pause"></i>';
        audioPlayer.play();
    }
    
    // Pause song
    function pauseSong() {
        isPlaying = false;
        musicPlayer.classList.remove('playing');
        playBtn.innerHTML = '<i class="fas fa-play"></i>';
        audioPlayer.pause();
    }
    
    // Next song
    function nextSong() {
        if (isRepeated) {
            audioPlayer.currentTime = 0;
            playSong();
            return;
        }
        
        currentSongIndex++;
        if (currentSongIndex >= songs.length) {
            currentSongIndex = 0;
        }
        loadSong(currentSongIndex);
        if (isPlaying) {
            playSong();
        }
    }
    
    // Previous song
    function prevSong() {
        if (audioPlayer.currentTime > 3) {
            audioPlayer.currentTime = 0;
            return;
        }
        
        currentSongIndex--;
        if (currentSongIndex < 0) {
            currentSongIndex = songs.length - 1;
        }
        loadSong(currentSongIndex);
        if (isPlaying) {
            playSong();
        }
    }
    
    // Update progress bar
    function updateProgressBar() {
        const { currentTime, duration } = audioPlayer;
        const progressPercent = (currentTime / duration) * 100;
        progressBar.value = progressPercent;
        
        // Update time displays
        currentTimeEl.textContent = formatTime(currentTime);
        
        if (duration) {
            durationEl.textContent = formatTime(duration);
        }
    }
    
    // Set progress bar
    function setProgressBar(e) {
        const width = this.clientWidth;
        const clickX = e.offsetX;
        const duration = audioPlayer.duration;
        audioPlayer.currentTime = (clickX / width) * duration;
    }
    
    // Format time
    function formatTime(seconds) {
        const mins = Math.floor(seconds / 60);
        const secs = Math.floor(seconds % 60);
        return `${mins}:${secs < 10 ? '0' : ''}${secs}`;
    }
    
    // Set volume
    function setVolume() {
        audioPlayer.volume = this.value;
    }
    
    // Toggle shuffle
    function toggleShuffle() {
        isShuffled = !isShuffled;
        shuffleBtn.classList.toggle('active');
        
        if (isShuffled) {
            // Create a shuffled queue
            shuffledQueue = [...songs];
            for (let i = shuffledQueue.length - 1; i > 0; i--) {
                const j = Math.floor(Math.random() * (i + 1));
                [shuffledQueue[i], shuffledQueue[j]] = [shuffledQueue[j], shuffledQueue[i]];
            }
            songs.splice(0, songs.length, ...shuffledQueue);
        } else {
            // Restore original queue
            songs.splice(0, songs.length, ...originalQueue);
        }
        
        // Update current song index
        const currentSong = originalQueue[currentSongIndex];
        currentSongIndex = songs.findIndex(song => song.title === currentSong.title);
        
        updateQueue();
    }
    
    // Toggle repeat
    function toggleRepeat() {
        isRepeated = !isRepeated;
        repeatBtn.classList.toggle('active');
    }
    
    // Update song queue
    function updateQueue() {
        songQueue.innerHTML = '';
        songs.forEach((song, index) => {
            const li = document.createElement('li');
            li.textContent = `${song.title} - ${song.artist}`;
            li.addEventListener('click', () => {
                currentSongIndex = index;
                loadSong(currentSongIndex);
                if (isPlaying) {
                    playSong();
                }
            });
            if (index === currentSongIndex) {
                li.classList.add('playing');
            }
            songQueue.appendChild(li);
        });
    }
    
    // Event listeners
    playBtn.addEventListener('click', () => {
        isPlaying ? pauseSong() : playSong();
    });
    
    prevBtn.addEventListener('click', prevSong);
    nextBtn.addEventListener('click', nextSong);
    
    audioPlayer.addEventListener('timeupdate', updateProgressBar);
    audioPlayer.addEventListener('ended', nextSong);
    audioPlayer.addEventListener('loadedmetadata', updateProgressBar);
    
    progressBar.addEventListener('click', setProgressBar);
    volumeSlider.addEventListener('input', setVolume);
    
    shuffleBtn.addEventListener('click', toggleShuffle);
    repeatBtn.addEventListener('click', toggleRepeat);
    
    // Initialize player
    initPlayer();
});

How It Works

  • Play/Pause Controls: The central play/pause button toggles audio playback and updates the button icon.
  • Next/Previous Tracks: Buttons let you navigate forward or backward through the playlist.
  • Progress Bar: A clickable progress bar displays how far the track has played and lets users seek to any part by clicking.
  • Volume Slider: Adjust the volume smoothly with a slider.
  • Shuffle & Repeat: Toggle shuffle for random playback or repeat to loop the current track.
  • Interactive Queue: A list shows upcoming tracks; clicking any track jumps to it immediately.
  • Responsive Design: The CSS ensures the player looks good and works well on desktops, tablets, and phones.

Try It Yourself!

Feel free to copy the code snippets above, tweak the styles, add your own tracks, and create your unique music experience.

Happy coding and happy listening! 🎵

Y2A Post

Discover the innovative work in AI-generated blogs, seamlessly blending technology with creativity. This unique approach not only offers fresh perspectives on various topics but also ensures that content is engaging and relevant.