<section class="device">
  <div class="device__top">
    <img class="album-art" src="https://res.cloudinary.com/andrewcanham/image/upload/v1579132801/everything-everything.jpg" alt="album art" />
    <img class="album-art" src="https://res.cloudinary.com/andrewcanham/image/upload/v1579132801/jamie-xx.jpg" alt="album art" />
    <img class="album-art" src="https://res.cloudinary.com/andrewcanham/image/upload/v1579132801/gidge.jpg" alt="album art" />
  </div>
  <div class="device__mid">
    <div class="info">
      <hgroup class="info__left">
        <h1 class="info__song">
          <span class="song">No Reptiles</span>
          <span class="song">Gosh</span>
          <span class="song">Norrland</span>
        </h1>
        <h2 class="info__artist">
          <span class="artist">by Everything Everything</span>
          <span class="artist">by Jamie xx</span>
          <span class="artist">by Gidge</span>
        </h2>
      </hgroup>

      <hgroup class="info__right">
        <h1 class="info__type">Playlist <span id="current-song">1</span> of 3</h1>
        <h2 class="info__type-name">My faves</h2>
      </hgroup>
    </div>

  </div>
  <div class="device__bottom">
    <div class="progress">
      <input id="slider" type="range" value="0" min="0" max="1800" step="1" />
    </div>
    <div class="equaliser"></div>
    <div class="controls">
      <button class="controls__round-button" id="previous-button">
        <svg width="10" height="10" viewBox="0 0 10 10" fill="none" xmlns="http://www.w3.org/2000/svg">
          <path d="M3.13672 5L9.5 0.5V9.5L3.13672 5ZM0.5 0.5H2.01172V9.5H0.5V0.5Z" />
        </svg>
        <span class="sr-only">Previous</span>
      </button>
      <button class="controls__round-button controls__round-button--large" id="play-button">
        <div class="play">
          <svg class="controls__play" width="14" height="18" viewBox="0 0 14 18" fill="none" xmlns="http://www.w3.org/2000/svg">
            <path d="M0.0195312 0.269531L13.7305 9L0.0195312 17.7305V0.269531Z"/>
          </svg>
          <span class="sr-only">Play</span>
        </div>
        <div class="pause">
          <svg width="16" height="18" viewBox="0 0 16 18" fill="none" xmlns="http://www.w3.org/2000/svg">
            <path d="M10.5195 0.269531H15.5V17.7305H10.5195V0.269531ZM0.5 17.7305V0.269531H5.48047V17.7305H0.5Z" fill="#728C98"/>
          </svg>
          <span class="sr-only">Pause</span>
        </div>
      </button>
      <button class="controls__round-button" id="next-button">
        <svg aria-hidden="true" focusable="false" width="10" height="10" viewBox="0 0 10 10" fill="none" xmlns="http://www.w3.org/2000/svg">
          <path d="M7.98828 0.5H9.5V9.5H7.98828V0.5ZM0.5 9.5V0.5L6.86328 5L0.5 9.5Z" />
        </svg>
        <span class="sr-only">Next</span>
      </button>
    </div>
  </div>
</section>
// font
@import url('https://fonts.googleapis.com/css?family=Roboto:300,700&display=swap');

// colours
$palest:  #F7FBFD;
$pale:    #EFF5F9;
$mid:     #AEBEC6;
$base:    #728C98;
$shade:   #4E86A5;
$bright:  #49C6FF;
$glow:    lighten($bright, 10%);

// variables
// ---------
// Change this to change the size of the player
// The entire design scales from this
$baseFontSize: 12px;



html {
  font-size: $baseFontSize;  
}

body {
  background: $pale;
  color: $base;
  font-family: 'Roboto', sans serif;
  font-weight: 300;
}

.sr-only:not(:focus):not(:active) {
  clip: rect(0 0 0 0); 
  clip-path: inset(100%);
  height: 1px;
  overflow: hidden;
  position: absolute;
  white-space: nowrap; 
  width: 1px;
}

// device styling, layout
.device {
  background: $palest;
  border-radius: 2.4rem;
  box-shadow: 2rem 2rem 8rem rgba($shade, 0.09), 1rem 1rem 4rem rgba($shade, 0.09), inset 4rem 4rem 10rem rgba($shade, 0.05);
  display: flex;
  flex-direction: column;
  height: 50rem;
  left: 50%;
  overflow: hidden;
  position: absolute;
  top: 50%;
  transform: translate3D(-50%,-50%,0);
  width: 26.8rem;
}

.device__top {
  background: rgba(255,255,255,0.6);
  height: 27.2rem;
  overflow: hidden;
  position: relative;
}

.album-art {
  height: 100%;
  object-fit: cover;
  width: 100%;
  position: absolute;
  transform: translateY(100%);
}
.album-art.active {
  transform: translateY(0);
}

.device__mid {
  flex: 1;
}

// information about current track, playlist etc.
.info {
  display: flex;
  font-size: 0.9rem;
  padding: 2rem 3rem;
}

.info__right {
  flex: 1;
  text-align: right;
}

.info__song {
  font-weight: 700;
  height: 1.6rem;
  margin: 0;
  overflow: hidden;
  padding: 0 0 0.4rem;
  position: relative;
}
.song {
  display: block;
  position: absolute;
  transform: translateY(150%);
}
.song.active {
  transform: translateY(0);
}
.info__artist {
  font-size: 1rem;
  font-weight: 300;
  height: 1.2rem;
  margin: 0;
  overflow: hidden;
  padding: 0;
  position: relative;
  width: 12rem;
}
.artist {
  display: block;
  left: 0;
  top: 0;
  position: absolute;
  transform: translateY(150%);
}
.artist.active {
  transform: translateY(0);
}
.info__type {
  color: $mid;
  font-size: 0.8rem;
  font-weight: 700;
  margin: 0.4rem 0 0.3rem;
  padding: 0 0 0.3rem;
  text-transform: uppercase;
}
.info__type-name {
  font-size: 1rem;
  font-weight: 300;
  margin: 0;
  padding: 0;
}

// controls
.controls {
  align-items: center;
  display: flex;
  justify-content: center;
}

.progress {
  height: 0.5rem;
  margin: 3rem 0 3.6rem;
  position: relative;
}

#play-button {
  .pause {
    display: none;
  }
  .play {
    display: block;
  }
}
#play-button.pause {
  .pause {
    display: block;
  }
  .play {
    display: none;
  }
}

.controls__round-button {
  background: rgba(#fff, 0.5);
  border-radius: 10rem;
  box-shadow: 
    1rem 1rem 4rem rgba(78, 134, 165, 0.09), 
    0.5rem 0.5rem 2rem rgba(78, 134, 165, 0.09), 
    -0.5rem -1.5rem 2rem rgba(255, 255, 255, 1), 
    inset 1rem 1rem 2.3rem rgba(78, 134, 165, 0.05), 
    0px 0px 0.1rem #FFFFFF, 
    inset 0.1rem 0.1rem 0 #FFFFFF;
  height: 5rem;
  margin: 0 1rem 3rem;
  position: relative;
  transition: box-shadow 0.05s ease-in;
  width: 5rem;
  svg {
    height: 1.6rem;
    left: 50%;
    position: absolute;
    top: 50%;
    transform: translate3d(-50%,-50%,0);
    width: 1.6rem;
    path {
      fill: $base;
      transition: fill 0.05s ease-in;
    }
  }
}
.controls__round-button:active {
  * {
    fill: $bright;
    filter: drop-shadow(0 0 0.1rem rgba($glow, 0.5));
  }
  box-shadow:
    1rem 1rem 4rem rgba(78, 134, 165, 0), 
    0 0.1rem 0.1rem rgba(78, 134, 165, 0.25), 
    -0.5rem -1.5rem 2rem rgba(255, 255, 255, 0), 
    inset 1rem 1rem 2.3rem rgba(78, 134, 165, 0.05), 
    0 0.1rem 0.1rem rgba(255,255,255,1), 
    inset 0.1rem -0.1rem 0 rgba(255,255,255,0);
}
.controls__round-button--large {
  height: 7.5rem;
  text-align: center;
  width: 7.5rem;
  svg {
    height: 2.6rem;
    width: 2.6rem;
  }
}
.controls__play {
  margin-left: 0.4rem;
}
// button reset
button {
  border: none;
  color: $base;
  cursor: pointer;
  display: inline-block;
  font-family: "roboto", sans-serif;
  font-size: 1rem;
  line-height: 1;
  margin: 0;
  padding: 1rem;
  text-align: center;
  text-decoration: none;
  -webkit-appearance: none;
  -moz-appearance: none;
}

button:hover,
button:focus {
  background: #fff;
}

button:focus {
  outline: none;
}

button:active {

}



// slider
input[type=range] {
  background: transparent;
  height: 2.5rem;
  -webkit-appearance: none;
  margin: 0.1rem 3rem;
  width: calc(100% - 6rem);
}
input[type=range]:focus {
  outline: none;
}
input[type=range]::-webkit-slider-runnable-track {
  width: 100%;
  height: 0.5rem;
  cursor: pointer;
  animate: 0.2s;
  border: 0;

  background: rgba(78, 134, 165, 0.03);
  border-radius: 1rem;
  bottom: 0;
  box-shadow: 
    0.3rem 0.3rem 1rem #FFFFFF, 
    -0.3rem -0.2rem 0.8rem rgba(78, 134, 165, 0.03), 
    inset 1rem 1rem 2.3rem rgba(78, 134, 165, 0.05), 
    inset 0.1rem 0.1rem 0 rgba(78, 134, 165, 0.05);
}
input[type=range]::-webkit-slider-thumb {
  border: 0;
  cursor: pointer;
  -webkit-appearance: none;
  margin-top: -6px;

  background: $palest;
  border-radius: 1rem;
  box-shadow: 
    0.2rem 0.2rem 1.2rem rgba(78, 134, 165, 0.12), 
    0.1rem 0.1rem 0.5rem rgba(78, 134, 165, 0.12), 
    0 0 0.1rem #fff, 
    inset 0.2rem 0.2rem 0.5rem rgba(78, 134, 165, 0.05), 
    inset 0.2rem 0.2rem 0 #fff;
  height: 1.4rem;
  padding: 0;
  width: 1.4rem;
}
input[type=range]::-webkit-slider-thumb:hover {
  background: #fff;
}

input[type=range]:focus::-webkit-slider-runnable-track {
  background: rgba($bright, 0.5);
}
input[type=range]::-moz-range-track {
  width: 100%;
  height: 0.5rem;
  cursor: pointer;
  animate: 0.2s;
  border: 0;

  background: rgba(78, 134, 165, 0.03);
  border-radius: 1rem;
  bottom: 0;
  box-shadow: 
    0.3rem 0.3rem 1rem #FFFFFF, 
    -0.3rem -0.2rem 0.8rem rgba(78, 134, 165, 0.03), 
    inset 1rem 1rem 2.3rem rgba(78, 134, 165, 0.05), 
    inset 0.1rem 0.1rem 0 rgba(78, 134, 165, 0.05);
}
input[type=range]::-moz-range-thumb {
  border: 0;
  cursor: pointer;
  -webkit-appearance: none;
  margin-top: -6px;

  background: $palest;
  border-radius: 1rem;
  box-shadow: 
    0.2rem 0.2rem 1.2rem rgba(78, 134, 165, 0.12), 
    0.1rem 0.1rem 0.5rem rgba(78, 134, 165, 0.12), 
    0 0 0.1rem #fff, 
    inset 0.2rem 0.2rem 0.5rem rgba(78, 134, 165, 0.05), 
    inset 0.2rem 0.2rem 0 #fff;
  height: 1.4rem;
  padding: 0;
  width: 1.4rem;
}
input[type=range]::-ms-track {
  width: 100%;
  height: 0.5rem;
  cursor: pointer;
  animate: 0.2s;
  border: 0;

  background: rgba(78, 134, 165, 0.03);
  border-radius: 1rem;
  bottom: 0;
  box-shadow: 
    0.3rem 0.3rem 1rem #FFFFFF, 
    -0.3rem -0.2rem 0.8rem rgba(78, 134, 165, 0.03), 
    inset 1rem 1rem 2.3rem rgba(78, 134, 165, 0.05), 
    inset 0.1rem 0.1rem 0 rgba(78, 134, 165, 0.05);
}
input[type=range]::-ms-fill-lower {

}
input[type=range]::-ms-fill-upper {

}
input[type=range]::-ms-thumb {
  border: 0;
  cursor: pointer;
  -webkit-appearance: none;
  margin-top: -6px;

  background: $palest;
  border-radius: 1rem;
  box-shadow: 
    0.2rem 0.2rem 1.2rem rgba(78, 134, 165, 0.12), 
    0.1rem 0.1rem 0.5rem rgba(78, 134, 165, 0.12), 
    0 0 0.1rem #fff, 
    inset 0.2rem 0.2rem 0.5rem rgba(78, 134, 165, 0.05), 
    inset 0.2rem 0.2rem 0 #fff;
  height: 1.4rem;
  padding: 0;
  width: 1.4rem;
}
input[type=range]:focus::-ms-fill-lower {

}
input[type=range]:focus::-ms-fill-upper {

}
View Compiled

// set variables
let currentSong = 0, maxSong, playing = false, position = 0, maxPosition = 1800, pause = false;

// grab relevant element references
const elements = {
  images: document.getElementsByClassName("album-art"),
  songs: document.getElementsByClassName("song"),
  artists: document.getElementsByClassName("artist"),
  play: document.getElementById("play-button"),
  previous: document.getElementById("previous-button"),
  next: document.getElementById("next-button"),
  currentSong: document.getElementById("current-song"),
  slider: document.getElementById("slider")
}

// controlling the DOM
function next() {
  updateDOM('remove');
  currentSong++;
  if (currentSong > maxSong) {
    currentSong = 0;
  }
  updateDOM('add');
  elements.slider.value = 0;
  position = 0;
}


function previous() {
  updateDOM('remove');
  currentSong--;
  if (currentSong < 0) {
    currentSong = maxSong;
  }
  updateDOM('add');
  elements.slider.value = 0;
}

function updateDOM(action) {
  elements.currentSong.innerHTML = currentSong + 1;
  if (action === 'add') {
    elements.images[currentSong].classList.add("active");
    elements.songs[currentSong].classList.add("active");
    elements.artists[currentSong].classList.add("active");
  } else {
    elements.images[currentSong].classList.remove("active");
    elements.songs[currentSong].classList.remove("active");
    elements.artists[currentSong].classList.remove("active");
  }
}

function playBar() {
  if (!pause) {
    setTimeout(function() {
      elements.slider.value = position++;
      if (position > maxPosition) {
        position = 0;
        next();
      }
      playBar();
    }, 10);
  }
}

function play() {
  if (!playing) {
    pause = false;
    playBar();
    elements.play.classList.add("pause");
  } else {
    pause = true;
    elements.play.classList.remove("pause");
  }
  playing = !playing;
}

function sliderChange() {
  position = elements.slider.value;
}

// initial setup
function init() {
  // setup first image
  elements.images[currentSong].classList.toggle("active");
  elements.songs[currentSong].classList.toggle("active");
  elements.artists[currentSong].classList.toggle("active");
  maxSong = elements.images.length - 1;
  // event listeners for controls
  elements.next.addEventListener("click", function() {
    next();
  });
  elements.previous.addEventListener("click", function() {
    previous();
  });
  elements.play.addEventListener("click", function(){
    play();
  });
  elements.slider.oninput = sliderChange;
}



init();


External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.