<div class="container">
  <div class="progress">
    <div class="percent"></div>
  </div>
  <div class="steps">
    <div class="step" id="0"></div>
    <div class="step" id="1"></div>
    <div class="step" id="2"></div>
    <div class="step" id="3"></div>
  </div>
</div>
body {
  margin: 0;
  padding: 0;
}
.container {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}
.steps {
  position: relative;
  display: flex;
  justify-content: space-between;
  width: 200px;
}
.step {
  width: 20px;
  height: 20px;
  background: #fff;
  border: 2px solid #ACACA6;
  border-radius: 50%;
  cursor: pointer;
  transition: background 1s;
}
.step.selected {
  border: 2px solid #4B81BD;   
}
.step.completed {
  border: 2px solid #4B81BD;
  background: #4B81BD; 
}
.progress {
  position: absolute;
  width: 100%;
  height: 50%;
  border-bottom: 2px solid #ACACA6;
  z-index: -1;
}
.percent {
  position: absolute;
  width: 0;
  height: 100%;
  border-bottom: 2px solid #4B81BD;
  z-index: 1;
  transition: width 1s;
}
let els = document.getElementsByClassName('step');
let steps = [];
Array.prototype.forEach.call(els, (e) => {
  steps.push(e);
  e.addEventListener('click', (x) => {
    progress(x.target.id);
  });
});

function progress(stepNum) {
  let p = stepNum * 30;
  document.getElementsByClassName('percent')[0].style.width = `${p}%`;
  steps.forEach((e) => {
    if (e.id === stepNum) {
      e.classList.add('selected');
      e.classList.remove('completed');
    }
    if (e.id < stepNum) {
      e.classList.add('completed');
    }
    if (e.id > stepNum) {
      e.classList.remove('selected', 'completed');
    }
  });
}

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.