ビフォーアフタースライダーとは

2 枚の画像を重ねて表示し、境界線をドラッグして施工前後などを比較できる部品。

概要

「施工前」と「施工後」のような 2 枚の画像を同じ位置に重ねて表示し、中央の境界線をドラッグすると 片方の画像がもう片方の上から現れて切り替わる部品です。リフォームやダイエット、写真加工のビフォー アフターを直感的に見せたいときに使われます。

別名

表記ゆれ:ビフォーアフタースライダー、比較スライダー、画像比較、before after slider

「比較スライダー」は画像に限らず 2 つのコンテンツを比較する用途全般を指す、やや広い言い方です。

AI への伝え方

「ビフォーアフタースライダーを作って」で通じます。境界線をドラッグで操作するか、input type="range" のようなスライダーで操作するかは実装が分かれる点なので、操作方法のイメージがあれば伝えてください。 画像を clip-path で隠すか、要素の幅そのものを変えて隠すかも実装の選択肢としてあります。

似たパーツとの違い

「カルーセル」は複数の画像を前へ・次へと順番に 1 枚ずつ切り替えるのに対し、ビフォーアフタースライダーは 常に 2 枚を同時に重ねて表示し、その境界の位置を連続的に動かして見比べる点が異なります。

デモ

コード

HTML
<div class="before-after-slider-demo">
  <div class="before-after-slider-demo__frame">
    <div class="before-after-slider-demo__after" aria-hidden="true"></div>
    <div class="before-after-slider-demo__before" aria-hidden="true"></div>
    <div class="before-after-slider-demo__divider" aria-hidden="true"></div>
    <span class="before-after-slider-demo__label before-after-slider-demo__label--before" aria-hidden="true">Before</span>
    <span class="before-after-slider-demo__label before-after-slider-demo__label--after" aria-hidden="true">After</span>
  </div>
  <input class="before-after-slider-demo__range" type="range" min="0" max="100" value="50" aria-label="比較位置" />
</div>
CSS
.before-after-slider-demo {
  max-width: 320px;
  font-family: sans-serif;
}

.before-after-slider-demo__frame {
  position: relative;
  height: 160px;
  overflow: hidden;
  border-radius: 8px;
}

.before-after-slider-demo__after {
  position: absolute;
  inset: 0;
  background: linear-gradient(135deg, #b3b3b3, #666666);
}

.before-after-slider-demo__before {
  position: absolute;
  inset: 0;
  background: linear-gradient(135deg, #0017c1, #333333);
  clip-path: inset(0 50% 0 0);
}

.before-after-slider-demo__divider {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 50%;
  width: 3px;
  margin-left: -1.5px;
  background: #ffffff;
  box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.15);
}

.before-after-slider-demo__label {
  position: absolute;
  top: 8px;
  padding: 2px 8px;
  border-radius: 4px;
  background: rgba(0, 0, 0, 0.35);
  color: #ffffff;
  font-size: 11px;
}

.before-after-slider-demo__label--before {
  left: 8px;
}

.before-after-slider-demo__label--after {
  right: 8px;
}

.before-after-slider-demo__range {
  display: block;
  width: 100%;
  margin-top: 12px;
}
JS
const range = document.querySelector(".before-after-slider-demo__range");
const before = document.querySelector(".before-after-slider-demo__before");
const divider = document.querySelector(".before-after-slider-demo__divider");

function update(value) {
  before.style.clipPath = `inset(0 ${100 - value}% 0 0)`;
  divider.style.left = `${value}%`;
}

range.addEventListener("input", () => update(range.value));
update(range.value);