![「react-compare-slider」を使ったBefore/After画像比較スライダーの実装方法を示すシステム図。中央で開発者がAI生成UIの改善を説明し、React、TypeScript、Tailwind、タッチ操作、アクセシビリティなど、実装に必要な要素が網羅的に描かれている。](https://wakatchi.dev/wp-content/uploads/2026/05/20260103-110539-before-after-image-comparison-slider-implementation-eyecatch-1.webp)

## 背景

正直なところ、最初は画像を並べるだけで十分だと考えていました。

しかし、実際に使ってみるとスライダーの重要性に気づきました。

Webアプリケーションの結果画面では、AIが生成したデザイン案のBefore/After画像を表示していました。
しかし、従来は2枚の画像を並べて表示するだけでした。

ユーザーが細かい違いを比較しにくいという課題がありました。
そこで、スライダーで重ねて比較できるインタラクティブなUIに改善することになりました。

**ReactでBefore/After比較UIを実装したい方にとって、この記事は実践的なガイドとなります。**

## こんな人におすすめ

この記事は以下のような方に役立ちます。

- ReactでBefore/After比較UIを実装したい方
- react-compare-sliderの使い方を学びたい方
- 画像比較スライダーを簡単に作成したい方
- タッチデバイス対応・アクセシビリティ対応の実装に関心がある方
- UIコンポーネントの設計パターンを学びたい方

## 目次

- [背景](#背景)
- [こんな人におすすめ](#こんな人におすすめ)
- [Before/After画像比較スライダーとは](#beforeafter画像比較スライダーとは)
- [要件](#要件)
- [実装方針](#実装方針)
- [ポイント](#ポイント)
- [react-compare-sliderのAPI活用](#react-compare-sliderのapi活用)
- [CSSスコープ化](#cssスコープ化)
- [アクセシビリティ対応](#アクセシビリティ対応)
- [学び](#学び)
- [よくある質問](#よくある質問)
- [まとめ](#まとめ)

## Before/After画像比較スライダーとは

Before/After画像比較スライダーとは、2枚の画像を重ねて表示し、スライダーをドラッグすることで比較できるインタラクティブなUIコンポーネントです。

**主な特徴:**

- ドラッグ操作でBefore/Afterの境界線を移動
- 重ねて表示することで細かい違いを比較可能
- タッチデバイスに対応していればモバイルでも操作可能
- 写真比較サイトや、リフォーム事例、美容施術のビフォーアフター表示などで活用されています

Reactでは、react-compare-sliderというライブラリを使うことで、この機能を簡単に実装できます。

> **💡 外部リンク**: [react-compare-slider公式ドキュメント](https://github.com/react-compare-slider/react-compare-slider) - GitHubリポジトリで詳細なAPIリファレンスを確認できます。

## 要件

スライダー機能の要件を整理します。

``mermaid
flowchart TD
A[Before/After比較機能] --> B[スライダー操作] A --> C[デバイス対応] A --> D[アクセシビリティ]
B --> B1[ドラッグで比較] B --> B2[初期位置: 50%]
C --> C1[タッチデバイス対応] C --> C2[ハンドルサイズ: 48px以上]
D --> D1[キーボード操作対応] D --> D2[未ログイン時は無効化]
style A fill:#e0e7ff
style B fill:#d1fae5
style C fill:#fef3c7
style D fill:#fce7f3
`

- スライダーをドラッグしてBefore/Afterを重ねて比較
- タッチデバイス対応(モバイルでの操作性確保)
- スライダー位置の初期値は中央(50%)
- モバイルでも操作しやすいハンドルサイズ(48px以上)
- キーボード操作対応(アクセシビリティ)
- 未ログイン時はスライダー操作を無効化してログイン促進

## 実装方針

実装の方針を決定しました。

`mermaid
graph TD
A[実装方針] --> B[ライブラリ選定] A --> C[コンポーネント設計] A --> D[統合] A --> E[スタイル実装]
B --> B1[react-compare-slider] B1 --> B2[タッチ対応] B1 --> B3[キーボード対応] B1 --> B4[disabled対応]
C --> C1[比較スライダーコンポーネント] C1 --> C2[Props設計] C1 --> C3[ハンドル: 48x48px]
D --> D1[結果表示コンポーネント統合] D1 --> D2[2画像レイアウト] D1 --> D3[3画像レイアウト]
E --> E1["CSSレイヤー"] E1 --> E2[ラベル表示] E1 --> E3[disabledオーバーレイ]
style A fill:#e0e7ff
style B fill:#d1fae5
style C fill:#fef3c7
style D fill:#fce7f3
style E fill:#ddd6fe
`

### 1. ライブラリ選定:
react-compare-sliderを採用

- タッチデバイス対応が組み込み済み
- キーボードナビゲーション対応(
keyboardIncrement prop)
- ゼロ依存で軽量
-
disabled propが組み込み済み

> **💡 外部リンク**: [Tailwind CSS v4公式ドキュメント](https://tailwindcss.com/docs/v4) - 本記事で使用しているTailwind CSS v4の最新情報を確認できます。

### 2. コンポーネント設計: 比較スライダーコンポーネントを新規作成

- Props: beforeImage, afterImage, beforeAlt, afterAlt, initialPosition, disabled, showLabels, className
- ハンドル: green-500色、48x48px
- トランジション: 0.2s ease-out

### 3. 結果表示コンポーネント統合

- 2画像レイアウト(パターンA): スライダーでBefore/After表示
- 3画像レイアウト(パターンB): メイン画像をスライダー化、サブ画像は別枠
- モーダルボタン: スライダー下部に「Before拡大」「After拡大」ボタン配置

### 4. スタイル実装

-
@layer componentsで全スタイルをスコープ化
- ラベル: 左上「Before」、右上「After」(半透明黒背景 + backdrop-blur)
- disabled時オーバーレイ: ログインプロンプト表示
- レスポンシブ対応

## ポイント

### react-compare-sliderのAPI活用

主要なPropsの使い方を解説します。

`tsx
// Before画像コンポーネント(alt属性でアクセシビリティ対応)
<ReactCompareSliderImage
src={beforeImage}
alt="Before: 変更前のデザイン"
/>

// After画像コンポーネント(alt属性でアクセシビリティ対応)
<ReactCompareSliderImage
src={afterImage}
alt="After: 変更後のデザイン"
/>

// メインのスライダーコンポーネント
<ReactCompareSlider
itemOne={<ReactCompareSliderImage src={beforeImage} alt={beforeAlt} />}
itemTwo={<ReactCompareSliderImage src={afterImage} alt={afterAlt} />}
position={initialPosition}
disabled={disabled}
handle={
<ReactCompareSliderHandle
buttonStyle={{
backgroundColor: '#22c55e', // green-500
width: 48,
height: 48,
}}
/>
}
keyboardIncrement="5%"
transition="0.2s ease-out"
/>
`

主要なPropsを説明します。

`mermaid
graph LR
A[ReactCompareSlider] --> B[itemOne] A --> C[itemTwo] A --> D[position] A --> E[disabled] A --> F[handle] A --> G[keyboardIncrement] A --> H[transition]
B --> B1[Before画像] C --> C1[After画像] D --> D1[初期位置: 50%] E --> E1[操作無効化] F --> F1[ハンドルカスタマイズ] G --> G1[キーボード移動量] H --> H1[アニメーション]
style A fill:#e0e7ff
style B fill:#d1fae5
style C fill:#fce7f3
`

**主要なProps一覧:**

| Props | 説明 | デフォルト値 |
|-------|------|-------------|
|
itemOne | Before側の画像(左側) | 必須 |
|
itemTwo | After側の画像(右側) | 必須 |
|
position | スライダー初期位置(0〜100) | 50 |
|
disabled | 操作を無効化するか | false |
|
handle | ハンドルのカスタマイズ | デフォルトハンドル |
|
keyboardIncrement | キーボード操作時の移動量 | "1%" |
|
transition | アニメーション効果 | なし |

### CSSスコープ化

Tailwind CSS v4で
@layer componentsを使用してグローバルスタイルの汚染を防止します。

`css
@layer components {
.compare-slider-container {
@apply relative w-full max-w-4xl mx-auto rounded-lg overflow-hidden shadow-md;
}
/* ... */
}
`

> **💡 関連記事**: [next/fontでNoto Sans JPをセルフホスティングする方法](/next/font-noto-sans-jp) - Tailwind CSS v4との統合方法について詳しく解説しています。

### アクセシビリティ対応

ライブラリ組み込みのアクセシビリティ機能を活用します。

- ライブラリ組み込みのキーボード操作(左右矢印キー)
-
role="slider" 自動設定
- disabled時は
aria-disabled="true" が自動設定
- ボタン要素はデフォルトでフォーカス可能

`mermaid
sequenceDiagram
participant U as ユーザー
participant S as Slider
participant K as キーボード

Note over U,S: タッチ操作
U->>S: ドラッグ
S->>S: 位置更新

Note over U,K: キーボード操作
U->>K: 矢印キー押下
K->>S: keyboardIncrement分移動
S->>U: 位置更新

Note over U,S: disabled時
U->>S: 操作試行
S-->>U: aria-disabled="true"
`

> **💡 外部リンク**: [WCAG 2.1 ガイドライン](https://www.w3.org/WAI/WCAG21/quickref/) - ウェブアクセシビリティの国際標準規格について確認できます。

## 学び

個人的に、この実装を通じて学んだことは大きかったです。

- **ライブラリ選定の重要性**: 要件に合ったライブラリを選ぶことで実装工数を大幅に削減できました。react-compare-sliderはdisabled、キーボード操作、タッチ対応が全て組み込み済みでした。

- **テストの構文エラー発見**: 大規模なテストファイルでは、ブラケットの数が合っているか確認が重要です。
grep -c '{' file && grep -c '}' fileで簡単にチェックできます。

- **button要素のフォーカス可能性**: ネイティブの
<button>要素はtabIndex属性なしでもデフォルトでフォーカス可能です。テストでtabIndex="0"をチェックするのは不適切でした。

- **Tailwind CSS v4のレイヤー**:
@layer componentsを使用することで、カスタムスタイルを適切なスコープに配置し、優先順位の問題を回避できます。

> **💡 関連記事**: [React Toast通知システムの実装ガイド](/react-toast-notification-system) - アクセシビリティ対応を考慮したUIコンポーネントの設計パターンについて詳しく解説しています。

## よくある質問

### Q1. react-compare-slider以外に、Before/After比較スライダーのライブラリはありますか?

**A**: はい、いくつかの選択肢があります。

| ライブラリ | 特徴 | 推奨ケース |
|-----------|------|-----------|
| react-compare-slider | タッチ対応・アクセシビリティ対応・軽量 | **推奨** |
| react-before-after-slider | シンプルで使いやすい | 基本的な比較のみ |
| react-compare-image | カスタマイズ性が高い | 高度なカスタマイズが必要な場合 |

個人的には、**react-compare-slider**が最もバランスが良いと感じています。

### Q2. モバイルでの動作はどうですか?

**A**: react-compare-sliderはタッチデバイス対応が組み込み済みなので、モバイルでもスムーズに動作します。

ただし、以下の点に注意が必要です。

- ハンドルサイズを48px以上にする(指で操作しやすくするため)
- ホバー時のツールチップはモバイルでは表示されない
-
touch-action: none CSSプロパティでスクロールとの競合を防ぐ

### Q3. アクセシビリティ対応はどの程度実装されていますか?

**A**: ライブラリ側で以下のアクセシビリティ機能が実装済みです。

-
role="slider" の自動設定
-
aria-valuenowaria-valueminaria-valuemax の自動設定
- キーボード操作(矢印キー)対応
-
aria-disabled の自動設定(disabled時)

開発者側で追加すべき対応は以下の通りです。

- 画像の
alt属性を適切に設定する
-
aria-labelでスライダーの目的を説明する
- キーボードフォーカスが見えるようにする

### Q4. 画像のサイズはどうすれば良いですか?

**A**: 2枚の画像は同じサイズにすることを推奨します。

- 幅と高さが一致している画像を使用する
- 異なるサイズの場合はCSSで調整するか、画像編集ソフトで統一する
- 最適なパフォーマンスを得るには、画像をWebP形式で圧縮してから使用する

### Q5. TypeScriptの型定義は提供されていますか?

**A**: はい、react-compare-sliderはTypeScriptの型定義を提供しています。

`typescript
import { ReactCompareSlider, ReactCompareSliderImage } from 'react-compare-slider';

// 型定義が自動補完されます
const beforeAlt: string = "Before: 画像の説明";
const afterAlt: string = "After: 画像の説明";
``

## まとめ

本記事では、ReactでBefore/After画像比較スライダー機能を実装する方法を解説しました。

### 実装のポイント

1. **react-compare-sliderを採用**: タッチ対応・キーボード対応・disabled機能を一括実装
2. **Tailwind CSS v4の@layer components**: スタイルをスコープ化
3. **アクセシビリティ対応**: ライブラリ組み込みで実現

### 得られた効果

- ユーザー体験の向上(スライダーで直感的に比較可能)
- モバイル対応(タッチデバイスで操作可能)
- アクセシビリティ対応(キーボード操作可能)

個人的には、このライブラリ選定で実装工数を大幅に削減できたと感じています。

要件に合ったライブラリを選ぶ重要性を教えてくれました。