Hello friends, today in this blog, we will learn how to create a music player with HTML, CSS, and JavaScript. In our previous blog, we saw how to create Weather App using HTML, CSS, and Javascript. You can check my other javascript projects after reading this blog.
Music is an integral part of our daily lives. Whether we’re working, exercising, or just relaxing, music has the power to enhance our moods and make our experiences more enjoyable. As a web developer, creating a music player using HTML, CSS, and JavaScript can be a fun and useful project to undertake.
In this tutorial, we will explore how to build a music player using these three core web technologies. We will cover the essential steps needed to create a functional music player, including setting up the HTML structure, writing the JavaScript code, and adding additional features such as a progress bar and volume control.
By the end of this tutorial, you will have a solid understanding of how to create a music player using HTML, CSS, and JavaScript. You will also have the skills necessary to customize the player to your liking and add additional functionality. So, let’s get started and create a music player that will help us enjoy our favorite tunes!
1 – Setting up the project
To begin creating a music player using HTML, CSS, and JavaScript, we need to set up the HTML structure. Here are the steps to follow:
- Create a new HTML file and name it index.html.
- Within the HTML file, create a basic structure by adding the <!DOCTYPE html> declaration and the <html> tags.
- Within the <html> tags, create the <head> and <body> tags.
- In the <head> tag, add the necessary metadata such as the title and any external stylesheets or scripts.
- Within the <body> tag, create a container for the music player using the <div> tag.
- Inside the container div, create a heading element that will display the name of the current track being played.
- Add an audio tag inside the container div, which will allow us to play and pause music.
- Create play and pause buttons using the <button> tag, and add them to the container div.
- Finally, add any additional elements or styling necessary to make the music player visually appealing.
You may like these:-
- How to Detect User Location Using Javascript
- Drag & Drop or Sortable List using HTML, CSS, and Sortable JS
- Custom Select Input with search option in HTML, CSS, and Javascript
- Cool sign-up page design using HTML, CSS, and Javascript
NOTE:
You Can Check Live Demo of this project and download code and image files from here.
2 – Code of HTML, CSS, and JavaScript Files
Here’s the good news: you don’t have to write all the code for this weather app from scratch! I have created a GitHub repository that contains all the HTML, CSS, and JavaScript code needed to build the app. You can check it out and use it as a starting point for your own weather app project.
HTML CODE </>
<!DOCTYPE html>
<html lang="en">
<head>
<!-- --------------------- Created By InCoder --------------------- -->
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Music Player - InCoderWeb</title>
<link rel="stylesheet" href="main.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css" />
</head>
<body>
<div class="musicPlayerMainContainer">
<div class="musicListArea">
<div class="topOptions">
<div class="topOptionsIcon">
<i class="fa-solid fa-arrow-left"></i>
</div>
<div class="title">Music Player</div>
<div class="topOptionsIcon">
<i class="fa-solid fa-ellipsis"></i>
</div>
</div>
<div class="albumDetails">
<div class="outerBox">
<img src="https://drive.google.com/uc?id=1mcO92astAN3SUYh0JTUzjqAv7p2sm07c&export=download" alt="Ablum Cover" class="albumCover" />
<button class="playAlbum"><i class="fa-solid fa-play"></i></button>
</div>
<p>My Album</p>
</div>
<div class="songsList">
</div>
</div>
<div class="mainPlayer">
<div class="musicPlayerArea">
<div class="topOptions">
<div class="topOptionsIcon backToAlbumBtn">
<i class="fa-solid fa-arrow-left"></i>
</div>
<div class="title">Now Playing</div>
<div class="topOptionsIcon">
<i class="fa-regular fa-heart"></i>
</div>
</div>
<div class="albumDetails">
<div class="outerBox">
<img src="Images/albumCover.jpg" alt="Ablum Cover" class="albumCover" />
</div>
<audio src="" id="mainAudio"></audio>
<div class="title"></div>
<div class="artist"></div>
</div>
<div class="playerButtons">
<div class="mainButtons">
<button class="prevBtn"><i class="fa-solid fa-backward-step"></i></button>
<button class="playSongBtn"><i class="fa-solid fa-pause"></i></button>
<button class="nextBtn"><i class="fa-solid fa-forward-step"></i></button>
</div>
<div class="progressBar">
<input type="range" name="" id="songTime" />
<div class="songTimings">
<div id="currentTime">00:00</div>
<div id="totalDuration">00:00</div>
</div>
</div>
<div class="secondaryButtons">
<button class="repeatBtn on"><i class="fa-solid fa-repeat"></i></button>
<button class="shuffleBtn" disabled><i class="fa-solid fa-shuffle"></i></button>
<button class="muteNUnmuteBtn"><i class="fa-solid fa-volume-high"></i></button>
<button class="returnToAlbumBtn"><i class="fa-solid fa-bars"></i></button>
</div>
</div>
</div>
</div>
</div>
<script src="songsList.js"></script>
<script src="script.js"></script>
</body>
</html>
CSS CODE </>
@import url("https://fonts.googleapis.com/css2?family=Ubuntu:ital,wght@0,300;0,400;0,500;0,700;1,300;1,400;1,500;1,700&display=swap");
/* --------------------- Created By InCoder --------------------- */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: "Ubuntu", sans-serif;
}
:root{
--progressWidth: 0%;
}
body {
display: flex;
height: 100vh;
align-items: center;
justify-content: center;
background-color: #3c4569;
}
.musicPlayerMainContainer {
width: 19rem;
height: 35rem;
overflow: hidden;
position: relative;
border-radius: 2rem;
background-color: #515e8f;
}
.musicListArea::-webkit-scrollbar {
width: 0px;
}
.musicListArea {
height: 100% !important;
overflow-y: scroll;
}
.musicListArea,
.musicListArea .topOptions {
width: 100%;
height: 8rem;
/* display: none; */
position: relative;
background: #262b42;
}
.topOptions {
display: flex;
padding: 1.5rem 1rem;
justify-content: space-between;
}
.topOptions .title {
color: #fff;
font-size: 1.2rem;
}
.topOptionsIcon {
width: 2.2rem;
height: 2.2rem;
display: flex;
cursor: pointer;
color: #515e8f;
font-size: 1.3rem;
align-items: center;
border-radius: 5rem;
justify-content: center;
transition: all 0.3s cubic-bezier(0, 0.61, 1, 1);
}
.topOptionsIcon:hover {
color: #fff;
background-color: #555e90;
}
.albumDetails .outerBox {
top: 5rem;
width: 5.5rem;
left: 1.5rem;
height: 5.5rem;
display: flex;
position: absolute;
align-items: center;
border-radius: 0.8rem;
justify-content: center;
background-color: #515e8f;
box-shadow: #3d476b 0 0 15px 2px;
}
.albumDetails .albumCover {
width: 5rem;
height: 4.3rem;
max-width: 4rem;
border-radius: 0.8rem;
}
.albumDetails p {
top: 5.9rem;
left: 8rem;
color: #fff;
font-weight: 700;
font-size: 1.5rem;
position: absolute;
}
.playAlbum {
right: -0.5rem;
bottom: -0.5rem;
border: none;
color: #fff;
width: 2.5rem;
height: 2.5rem;
cursor: pointer;
font-size: 1rem;
border-radius: 50%;
position: absolute;
backdrop-filter: blur(0.5px);
background-color: #404664;
transition: all 0.3s cubic-bezier(0, 0.61, 1, 1);
}
.playAlbum:hover {
box-shadow: #282b42 0 0 8px -3px;
}
.songsList {
margin-top: 4.5rem;
padding: 0rem 1rem;
padding-bottom: 4rem;
}
.songsList .song {
display: flex;
margin-bottom: 1rem;
align-items: center;
padding: 0.8rem 1rem;
border-radius: 1.2rem;
backdrop-filter: blur(0.5px);
background-color: #7e84a76b;
transition: transform 0.3s ease;
}
.songsList .song:hover {
transform: translateY(-0.2rem);
}
.songsList .song .icon {
border: none;
display: flex;
color: #fff;
width: 2.5rem;
height: 2.5rem;
cursor: pointer;
font-size: 1rem;
border-radius: 50%;
align-items: center;
margin-right: 0.5rem;
justify-content: center;
backdrop-filter: blur(0.5px);
background-color: #404664;
transition: all 0.3s cubic-bezier(0, 0.61, 1, 1);
}
.songsList .song .icon:hover {
box-shadow: #282b42 0 0 8px -3px;
}
.songsList .song .details .info {
display: flex;
color: #ffffff96;
width: 12rem;
justify-content: space-between;
}
.songsList .song .details .info .artist {
font-size: 0.75rem;
margin-top: 0.1rem;
}
.songsList .song .details .info .duration {
font-size: 0.75rem;
}
.songsList .song .details .title {
color: #fff;
font-size: 1.2rem;
}
/* --------------------- Music Player Code --------------------- */
.musicPlayerArea {
width: 100%;
height: 12rem;
position: relative;
background: #262b42;
}
.mainPlayer {
top: 91%;
width: 100%;
height: 100%;
position: absolute;
transition: all .5s ease-in-out;
backdrop-filter: blur(1px);
background-color: #515e8f;
}
.mainPlayer.active {
top: 0%;
}
.musicPlayerArea .topOptions {
padding-top: 3rem;
position: relative;
}
.songTimings{
display: flex;
color: #ffffff94;
justify-content: space-between;
}
.musicPlayerArea .topOptions::before {
left: 41%;
content: "";
top: 1.5rem;
cursor: grab;
width: 3.5rem;
height: 0.3rem;
border-radius: 1rem;
position: absolute;
background-color: #fff;
}
.musicPlayerArea .albumDetails .outerBox {
top: 6rem;
left: 3.2rem;
display: flex;
width: 12.5rem;
height: 11.5rem;
position: absolute;
align-items: center;
border-radius: 0.8rem;
justify-content: center;
background-color: #515e8f;
box-shadow: #3d476b 0 0 15px 2px;
}
.musicPlayerArea .albumDetails .albumCover {
width: 11rem;
height: 10rem;
max-width: 100%;
border-radius: 0.8rem;
}
.musicPlayerArea .albumDetails .title {
color: #fff;
font-size: 1.6rem;
margin-top: 12rem;
text-align: center;
}
.musicPlayerArea .albumDetails .artist {
font-size: 0.8rem;
margin-top: 0.2rem;
color: #ffffff94;
text-align: center;
}
.playerButtons {
margin-top: 2rem;
}
.mainButtons,
.secondaryButtons {
display: flex;
justify-content: space-around;
}
.mainButtons button,
.secondaryButtons button {
color: #fff;
border: none;
width: 2.5rem;
height: 2.5rem;
cursor: pointer;
border-radius: 50%;
outline-offset: 1px;
background-color: #262b42;
transition: all 0.3s cubic-bezier(0, 0.61, 1, 1);
}
.mainButtons button:hover {
box-shadow: #282b42 0 0 8px -3px;
}
.mainButtons button:nth-child(1) {
margin-top: 0.4rem;
}
.mainButtons button:nth-child(3) {
margin-top: 0.4rem;
}
.mainButtons button:nth-child(2) {
width: 3.5rem;
height: 3.5rem;
font-size: 1.5rem;
}
.mainButtons button:focus,
.secondaryButtons button.on {
outline: 2px solid #262b42;
}
.secondaryButtons button:disabled{
background-color: #262b426b!important;
}
#songTime {
width: 100%;
margin-bottom: .5rem;
}
.progressBar{
margin: 1.5rem 1.4rem;
margin-top: .5rem;
margin-bottom: .8rem;
}
input[type="range"] {
-webkit-appearance: none;
appearance: none;
cursor: pointer;
position: relative;
border-radius: 1rem;
}
input[type="range"]::-webkit-slider-runnable-track {
background: #ffffff94;
height: 0.2rem;
}
input[type="range"]::-webkit-slider-thumb {
-webkit-appearance: none;
appearance: none;
margin-top: -7px;
border-radius: 1rem;
background-color: #262b42;
height: 1rem;
width: 1rem;
}
input[type="range"]:focus::-webkit-slider-thumb {
outline-offset: 1px;
outline: 1px solid #262b42;
}
input[type="range"]::before {
content: "";
top: 0;
left: 0%;
width: var(--progressWidth);
height: 150%;
position: absolute;
border-radius: 2px;
background-color: #262b42;
}
JavaScript CODE </>
const allSongs = [
{
id: "1",
name: "Falling Down",
artist: "Alex Skrindo",
image: "https://drive.google.com/uc?id=15bTbmGwT0ufWFIJ-pi2wXm3E5_mhLkB4&export=download",
src: "https://drive.google.com/uc?id=1AErADbHUjFwlJYEykZh5VfHvaZGOuacD&export=download",
},
{
id: "2",
name: "Everything",
artist: "JJL. Malarkey",
image: "https://drive.google.com/uc?id=1k9l98chcAjFCSBoF1A-mpUFm08BqGdzI&export=download",
src: "https://drive.google.com/uc?id=1xjCQsCQt6WNWDjX7T7ov6nIheit49hZx&export=download",
},
{
id: "3",
name: "Dreamer",
artist: "Alan Walker",
image: "https://drive.google.com/uc?id=1iYN0uTd9nLcy2O_qlrTAKR1bWpq5Vbyl&export=download",
src: "https://drive.google.com/uc?id=1WJRLLBPXf6VxwwkNhBTBoXs5-XhFcga_&export=download",
},
{
id: "4",
name: "094",
artist: "JOXION",
image: "https://drive.google.com/uc?id=16FkUQPPuZ-cli6_JjLBzyCc-f30N5YTo&export=download",
src: "https://drive.google.com/uc?id=1cEsAs0JQfY_0e32c2Ic8RIDQJuqFUh11&export=download",
},
{
id: "5",
name: "Immortal",
artist: "CITYWLKR",
image: "https://drive.google.com/uc?id=1Dh2N46sgkKJ1dV6kA6JAzJbjYKcK4nhp&export=download",
src: "https://drive.google.com/uc?id=1ht0O21NIodPWNkMOl4ny3fQp9IWovnpL&export=download",
},
]
const mainPlayBtn = document.querySelector('.playAlbum')
backToAlbumBtn = document.querySelector('.backToAlbumBtn')
songsList = document.querySelector('.songsList')
music = document.querySelector('#mainAudio')
playNPauseBtn = document.querySelector('.playSongBtn')
muteNUnmuteBtn = document.querySelector('.muteNUnmuteBtn')
returnToAlbumBtn = document.querySelector('.returnToAlbumBtn')
prevBtn = document.querySelector('.prevBtn')
nextBtn = document.querySelector('.nextBtn')
songTime = document.querySelector('#songTime')
repeatBtn = document.querySelector('.repeatBtn')
shuffleBtn = document.querySelector('.shuffleBtn')
mainPlayer = document.querySelector('.mainPlayer');
mainPlayBtn.addEventListener('click', (e) => {
mainPlayer.classList.add('active')
})
backToAlbumBtn.addEventListener('click', (e) => {
mainPlayer.classList.remove('active')
})
const loadMusic = (index) => {
document.querySelector('.musicPlayerArea .albumDetails .title').innerText = allSongs[index - 1].name
document.querySelector('.musicPlayerArea .albumDetails .artist').innerText = allSongs[index - 1].artist
document.querySelector('.musicPlayerArea .albumDetails .albumCover').src = allSongs[index - 1].image
music.setAttribute('data-currentIndex', index)
music.src = allSongs[index - 1].src
}
const openPlayer = (index) => {
mainPlayer.classList.add('muted', 'active', 'paused')
if (mainPlayer.classList.contains("paused")) {
playNPauseBtn.querySelector("i").classList.remove('fa-play')
playNPauseBtn.querySelector("i").classList.add('fa-pause')
}
loadMusic(index)
music.play()
}
const playMusic = () => {
mainPlayer.classList.add('paused')
playNPauseBtn.querySelector("i").classList.remove('fa-play')
playNPauseBtn.querySelector("i").classList.add('fa-pause')
music.play()
}
const pauseMusic = () => {
mainPlayer.classList.remove('paused')
playNPauseBtn.querySelector("i").classList.remove('fa-pause')
playNPauseBtn.querySelector("i").classList.add('fa-play')
music.pause()
}
playNPauseBtn.addEventListener('click', () => {
const isMusicPaused = mainPlayer.classList.contains("paused")
isMusicPaused ? pauseMusic() : playMusic()
})
const mute = () => {
mainPlayer.classList.remove('muted')
muteNUnmuteBtn.querySelector("i").classList.remove('fa-volume-high')
muteNUnmuteBtn.querySelector("i").classList.add('fa-volume-xmark')
music.volume = 0;
}
const unmute = () => {
mainPlayer.classList.add('muted')
muteNUnmuteBtn.querySelector("i").classList.remove('fa-volume-xmark')
muteNUnmuteBtn.querySelector("i").classList.add('fa-volume-high')
music.volume = 1;
}
muteNUnmuteBtn.addEventListener('click', () => {
const isMuted = mainPlayer.classList.contains("muted")
isMuted ? mute() : unmute()
})
returnToAlbumBtn.addEventListener('click', () => {
mainPlayer.classList.remove('active')
})
mainPlayBtn.addEventListener('click', () => {
openPlayer(1)
})
prevBtn.addEventListener('click', () => {
let currentIndex = music.getAttribute('data-currentIndex')
if ((currentIndex - 1) <= 0) {
loadMusic(1)
} else {
loadMusic(currentIndex - 1)
}
mainPlayer.classList.add('paused')
music.play()
})
nextBtn.addEventListener('click', () => {
let currentIndex = music.getAttribute('data-currentIndex')
if ((parseInt(currentIndex) + 1) >= allSongs.length) {
loadMusic(allSongs.length)
} else {
loadMusic(parseInt(currentIndex) + 1);
}
mainPlayer.classList.add('paused')
music.play()
})
music.addEventListener("timeupdate", (e) => {
const currentTime = e.target.currentTime;
const duration = e.target.duration;
let progressWidth = (currentTime / duration) * 100;
songTime.value = progressWidth
document.documentElement.style.cssText = `--progressWidth: ${progressWidth}%`;
let musicCurrentTime = document.querySelector('#currentTime');
musicDuration = document.querySelector('#totalDuration');
music.addEventListener("loadeddata", (e) => {
totalMin = Math.floor(music.duration / 60);
totalSec = Math.floor(music.duration % 60);
if (totalSec < 10) {
totalSec = `0${totalSec}`
}
musicDuration.innerHTML = `${totalMin}:${totalSec}`;
})
let currentMin = Math.floor(currentTime / 60);
currentSec = Math.floor(currentTime % 60);
if (currentSec < 10) {
currentSec = `0${currentSec}`
}
musicCurrentTime.innerHTML = `${currentMin}:${currentSec}`;
})
songTime.addEventListener('click', (e) => {
let progressWidthVal = songTime.clientWidth
clickedOffsetX = e.offsetX
songDuration = music.duration
music.currentTime = (clickedOffsetX / progressWidthVal) * songDuration
})
repeatBtn.addEventListener('click', () => {
if(repeatBtn.classList.contains("on")){
repeatBtn.classList.remove("on")
shuffleBtn.removeAttribute("disabled")
}else{
repeatBtn.classList.add("on")
shuffleBtn.setAttribute("disabled", "disabled")
shuffleBtn.classList.remove("on")
}
})
shuffleBtn.addEventListener('click', () => {
if(shuffleBtn.classList.contains("on")){
shuffleBtn.classList.remove("on")
repeatBtn.removeAttribute("disabled")
}else{
shuffleBtn.classList.add("on")
repeatBtn.setAttribute("disabled", "disabled")
repeatBtn.classList.remove("on")
}
})
music.addEventListener("ended", () => {
if(repeatBtn.classList.contains("on")){
music.currentTime = 0
music.play()
}
if(shuffleBtn.classList.contains("on")){
let randomIndex = Math.floor((Math.random() * allSongs.length) + 1)
console.log(randomIndex);
loadMusic(randomIndex)
music.play()
}
})
allSongs.forEach((song) => {
songsList.innerHTML += `<div class="song">
<div class="icon" onClick="openPlayer(${song.id})"><i class="fa-solid fa-play"></i></div>
<div class="details">
<div class="title">${song.name}</div>
<div class="info">
<div class="artist">${song.artist}</div>
</div>
</div>
</div>`;
})