<div id="js-splide" class="splide">
  <div class="splide__track">
    <ul class="splide__list">
      <li class="splide__slide"></li>
      <li class="splide__slide"></li>
      <li class="splide__slide"></li>
    </ul>
  </div>
</div>
.splide {
  margin-block: 24px;
  margin-inline: auto;
}

.splide__slide {
  height: 200px;
  background-color: #7ba57b;
}

.splide__pagination {
  margin-block-start: 8px;
  gap: 4px;
  position: static;
}

.splide__pagination li {
  display: flex;
  width: 40px;
  height: 4px;
}

.splide__pagination__page {
  width: 100%;
  height: 100%;
  margin: 0;
  border-radius: 0;
  background: #ededed;
  position: relative;
  opacity: 1;
  color: #193219;

  &::after {
    content: "";
    display: block;
    width: 100%;
    height: 100%;
    position: absolute;
    bottom: 0;
    will-change: width;
  }

  /* アクティブなスライドに紐づくページネーション */
  &.is-active {
    background: #ededed;
    transform: scale(1);

    &::after {
      width: var(--playing-rate);
      background: currentColor;
    }
  }
}
const splide = new Splide("#js-splide", {
  type: "loop",
  width: "80%",
  padding: "20%",
  gap: 10,
  autoplay: true,
  resetProgress: false, // ★
});

// ページネーションに自動再生の経過時間を付与する
document.addEventListener("DOMContentLoaded", () => {
  const pagination = splide.root.querySelector(".splide__pagination");
  splide.on("autoplay:playing", (rate) => {
    pagination.style.setProperty("--playing-rate", `${rate * 100}%`);
  });
});

splide.mount();
Run Pen

External CSS

  1. https://cdn.jsdelivr.net/npm/@splidejs/splide@4.1.4/dist/css/themes/splide-default.min.css

External JavaScript

  1. https://cdn.jsdelivr.net/npm/@splidejs/splide@4.1.4/dist/js/splide.min.js