JA EN

ビフォーアフタースライダーの実装 - 画像比較 UI の設計と最適化

· 約 9 分で読めます

画像比較スライダーの用途と設計要件

画像比較スライダー (Before/After Slider) は、2 枚の画像を重ね合わせ、ドラッグ操作で境界線を移動させることで視覚的に差異を確認できる UI コンポーネントです。写真編集のビフォーアフター、画像圧縮の品質比較、Web デザインの新旧比較、医療画像の経時変化など、幅広い場面で活用されています。

設計上の要件:

実装アプローチは大きく 3 つあります: CSS clip-path 方式、overflow: hidden + 幅制御方式、Canvas 描画方式です。それぞれにトレードオフがあり、用途に応じて最適な方式を選択します。本記事では最もパフォーマンスに優れた clip-path 方式を中心に解説します。

HTML 構造とセマンティクス - アクセシブルなマークアップ

画像比較スライダーの HTML 構造は、セマンティクスとアクセシビリティを考慮して設計します。スクリーンリーダーユーザーにも比較の意図が伝わり、キーボードで操作可能な構造にします。

推奨 HTML 構造:

<div class="comparison-slider" role="group" aria-label="画像比較"><div class="comparison-slider__before"><img src="before.webp" alt="処理前の画像" /><span class="comparison-slider__label">Before</span></div><div class="comparison-slider__after"><img src="after.webp" alt="処理後の画像" /><span class="comparison-slider__label">After</span></div><div class="comparison-slider__handle" role="slider" aria-label="比較位置" aria-valuemin="0" aria-valuemax="100" aria-valuenow="50" tabindex="0"></div></div>

マークアップのポイント:

ラベル表示は CSS の position: absolute で画像の左上/右上に配置し、スライダー操作時に隠れないよう z-index を調整します。ラベルのフォントサイズはコンテナ幅に応じて clamp(0.75rem, 2vw, 1rem) でスケールさせると、レスポンシブ環境で自然に見えます。

CSS 実装 - clip-path によるパフォーマンス最適化

clip-path を使用した実装は、GPU アクセラレーションが効きやすく、ドラッグ中のパフォーマンスに最も優れています。clip-path の変更はレイアウト再計算を発生させず、コンポジットレイヤーの更新のみで済むためです。

基本 CSS:

.comparison-slider { position: relative; overflow: hidden; cursor: col-resize; } .comparison-slider__before, .comparison-slider__after { position: absolute; inset: 0; } .comparison-slider__before img, .comparison-slider__after img { display: block; width: 100%; height: 100%; object-fit: cover; } .comparison-slider__after { clip-path: inset(0 0 0 50%); } .comparison-slider__handle { position: absolute; top: 0; bottom: 0; left: 50%; width: 4px; background: white; transform: translateX(-50%); box-shadow: 0 0 8px rgba(0,0,0,0.3); }

パフォーマンス最適化のポイント:

レスポンシブ対応: コンテナに aspect-ratio: 16/9 (または画像のアスペクト比) を設定し、幅 100% で高さを自動計算させます。画像は object-fit: cover でコンテナに合わせて表示し、アスペクト比が異なる画像でも破綻しない設計にします。

JavaScript 実装 - ドラッグ操作とイベント処理

スライダーのインタラクションを JavaScript で実装します。マウスイベントとタッチイベントの両方に対応し、Pointer Events API を使用することで統一的に処理できます。

コア実装のポイント:

キーボード操作の実装:

handle.addEventListener('keydown', (e) => { if (e.key === 'ArrowLeft') updatePosition(currentPercent - 1); if (e.key === 'ArrowRight') updatePosition(currentPercent + 1); if (e.key === 'Home') updatePosition(0); if (e.key === 'End') updatePosition(100); });

DOM 更新関数:

function updatePosition(percent) { percent = Math.max(0, Math.min(100, percent)); afterEl.style.clipPath = `inset(0 0 0 ${percent}%)`; handleEl.style.left = `${percent}%`; handleEl.setAttribute('aria-valuenow', Math.round(percent)); }

タッチデバイスでの注意点: touch-action: none をコンテナに設定し、ブラウザのデフォルトスクロール動作を抑制します。ただし、垂直スクロールは許可したい場合は touch-action: pan-y に変更し、水平方向のみスライダーが反応するようにします。

高度な機能 - アニメーション、遅延読み込み、複数インスタンス

基本実装に加え、ユーザー体験を向上させる高度な機能を実装します。

初期アニメーション (Onboarding):

画像の遅延読み込み:

複数インスタンスの管理:

縦方向スライダー: clip-path: inset(50% 0 0 0) で上下分割にし、ハンドルを水平に配置することで縦方向の比較も実現できます。data-direction="vertical" 属性で方向を切り替える設計にすると汎用性が高まります。

既存ライブラリの比較と選定基準

自前実装の代わりに、既存のライブラリを活用する選択肢もあります。プロジェクトの要件に応じて、自前実装とライブラリ利用のどちらが適切かを判断します。

主要ライブラリの比較:

選定基準:

自前実装を選ぶべきケース:

いずれの場合も、Core Web Vitals への影響を計測し、LCP (Largest Contentful Paint) を遅延させないよう画像の最適化 (WebP/AVIF 使用、適切なサイズ指定) を併せて実施してください。

関連記事

画像の差分比較手法 - ピクセル単位からセマンティック比較まで

画像の差分を検出・可視化する技術を体系的に解説。ピクセル比較、構造的類似度、知覚的差分など多角的なアプローチを紹介します。

レスポンシブ画像の実装ガイド - srcset, sizes, picture 要素の完全解説

デバイスの画面サイズや解像度に応じて最適な画像を配信するレスポンシブ画像の実装方法を、コード例とともに詳しく解説します。

HTML イメージマップの作り方と代替手段 - クリッカブルマップの実装ガイド

HTML の map 要素と area 要素を使ったイメージマップの実装方法を解説。レスポンシブ対応の課題と、SVG や CSS を使ったモダンな代替手段を具体的なコード例とともに紹介します。

スマホでの画像編集ベストプラクティス - モバイル環境での効率的な写真加工術

スマートフォンでの画像編集を効率化するテクニック。モバイルブラウザでの処理制約、メモリ管理、タッチ UI 設計、PWA での実装方法を実践的に解説します。

Web サイトの画像パフォーマンス監査 - Core Web Vitals 改善の実践ガイド

Web サイトの画像がパフォーマンスに与える影響を監査する方法を解説。LCP 改善、CLS 防止、転送量削減の具体的な手法を紹介します。

画像ギャラリーのパフォーマンス最適化 - 大量画像を高速表示するテクニック

数百枚以上の画像を含むギャラリーページのパフォーマンスを最適化する手法を解説。仮想スクロール、プログレッシブ読み込み、メモリ管理、レイアウト計算の効率化を実践的に紹介します。

関連用語