// from https://snippet.zone

const NUM = 8;
const NUM_M_1 = NUM - 1;
const ui = document.createElement('div')
ui.innerHTML = `
  <div class="ui">
    <div class="progress" data-ref>
      <div class="progressFill" data-ref></div>
    </div>
    <div class="text" data-ref>
    0% of 100%
    </div>
 
    <div class="dots" data-ref>
    ${
      `<div></div>`.repeat(NUM)
    }
    </div>
 
    <label>
      drag the slider...
      <input class="slider" type="range" min="0" max="100" step="1" value="0" data-ref/>
    </label>
  </div>
  <style>
    body {
      font-family: sans-serif;
    }
    .progress, .dots {
      position: relative;
      width: 80%;
      margin: 0 auto;
      height: 30px;
      border: 1px solid black;
    }
    .progressFill {
      height: 100%;
      width: 0;
      background: red;
    }
    .text {
      padding: 1em;
      background: #ccc;
      margin: .5em;
      font-weight: bold;
    }
    label {
      display: block;
      margin: 1em;
    }
    .slider {
      cursor: pointer;
    }
    .dots {
      border: none;
    }
    .dots div {
      height: 100%;
      width: ${100 / NUM}%;
      float: left;
      transition: background 400ms ease-out;
      background: transparent;
      border-radius: 500px;
      box-shadow: inset 0 0px 0 3px blue;
    }
    .dots div:nth-child(1) {
      background: red;
    }
 
  </style>
`;
document.body.appendChild(ui);
 
// select everything with a `data-ref`
const els = {};
;[...document.querySelectorAll('[data-ref]')]
  .forEach(el => {
    els[el.classList[0]] = el;
  });
 
function update(e) {
 
  // normal prog bar
  const val = e.target.value;
  els.progressFill.style.width = `${val}%`;
  els.text.innerHTML = `
    ${val}% of 100%
  `;
 
  // segmented dot prog bar
  const idx = Math.floor(val / (100 / NUM));
  if (idx < NUM) { 
    for (let i = 0; i < NUM; i++) {
      els.dots.children[i]
        .style.background = i <= idx ? 'red' : 'white'
    }
  }
}
 
els.slider.addEventListener('input', update);
els.slider.addEventListener('change', update);

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.