.png&w=3840&q=75)
今回の記事は Shopify App Store で提供されている、画像ビフォーアフター(Before After)スライダーアプリについての記事です。
ECサイトにおいて、商品の使用前・使用後や、加工前・加工後の変化を視覚的に伝えることは、購入を検討しているユーザーにとって非常に大きな判断材料になります。画像ビフォーアフタースライダーを導入すれば、2枚の画像をインタラクティブに比較できるため、静止画だけでは伝わりにくい変化を直感的に訴求できます。
この記事では、Shopify で画像 Before After スライダーを実現できるアプリを比較・紹介するとともに、Liquid テーマでのコーディング実装方法も解説します。
画像ビフォーアフタースライダーとは、2枚の画像を重ね合わせて表示し、ユーザーがスライダーハンドルをドラッグすることで「Before(変更前)」と「After(変更後)」を比較できるUIコンポーネントです。
一般的には、中央にスライダーバー(仕切り線)があり、左側にBefore画像、右側にAfter画像が配置されます。ユーザーがバーを左右にドラッグすると、表示される領域が変わり、2つの状態の違いをリアルタイムで確認できます。
主な用途としては以下のようなものがあります。
水平方向(左右)だけでなく、垂直方向(上下)のスライダーに対応しているものもあり、商品や用途に応じて最適な表示方法を選択できます。
Shopify ストアに画像ビフォーアフタースライダーを導入することで、以下のような利点が得られます。
商品変化の可視化: 使用前後の違いを1つのUI上で直感的に伝えることができ、テキストだけでは表現しきれない商品の効果を視覚的に訴求できます。
コンバージョン率の向上: 商品の効果や変化を具体的に示すことで、購入を迷っているユーザーの背中を押し、購入率の改善が期待できます。
ユーザーエンゲージメントの強化: スライダーをドラッグするというインタラクティブな操作が加わることで、ユーザーの滞在時間が伸び、ページへの関心度が高まります。
信頼性・透明性の向上: 実際の変化を隠さずに見せることで、ブランドへの信頼感が生まれ、ユーザーに安心して購入してもらえるようになります。
差別化による競合優位性: 多くのECサイトが静止画のみで商品を紹介する中、ビフォーアフタースライダーを活用することで、ストアの印象を強化し競合との差別化を図れます。
説明コストの削減: 長い説明文や複数枚の画像を並べなくても、1つのスライダーで商品の効果を端的に伝えられるため、ページ構成がシンプルになります。
モバイルフレンドリーな訴求: タッチ操作に対応したスライダーであれば、スマートフォンユーザーにも快適な比較体験を提供でき、モバイルコマースでの効果も発揮します。
SNSシェアの促進: ビジュアルインパクトのあるビフォーアフター比較は、ユーザーがSNSでシェアしたくなるコンテンツになりやすく、自然な拡散効果が期待できます。
多用途への展開: 商品ページだけでなく、ランディングページ、ブログ記事、キャンペーンページなど、さまざまなページで活用でき、ストア全体の表現力を高められます。
Shopify で画像ビフォーアフタースライダーアプリを選ぶ際には、以下のポイントを確認しましょう。
ここからは、Shopify App Store で提供されている画像ビフォーアフタースライダーアプリを紹介していきます。
Before/After画像をスライダーで並べて比較できるノーコードアプリ





アプリを使わずに、Shopify の Liquid テーマファイルにカスタムコードを追加して画像ビフォーアフタースライダーを実装する方法を紹介します。以下のコードをセクションファイル(例: sections/before-after-slider.liquid)として保存し、テーマに追加してください。
<div class="ba-slider-section">
<h2 class="ba-slider-title">{{ section.settings.title }}</h2>
<div class="ba-slider-container" id="ba-slider-{{ section.id }}">
<div class="ba-slider-image ba-slider-after">
<img src="{{ section.settings.after_image | image_url: width: 1200 }}" alt="After" loading="lazy">
<span class="ba-slider-label ba-label-after">{{ section.settings.after_label | default: 'After' }}</span>
</div>
<div class="ba-slider-image ba-slider-before">
<img src="{{ section.settings.before_image | image_url: width: 1200 }}" alt="Before" loading="lazy">
<span class="ba-slider-label ba-label-before">{{ section.settings.before_label | default: 'Before' }}</span>
</div>
<div class="ba-slider-handle">
<div class="ba-slider-line"></div>
<div class="ba-slider-circle">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<polyline points="15 18 9 12 15 6"></polyline>
</svg>
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<polyline points="9 18 15 12 9 6"></polyline>
</svg>
</div>
<div class="ba-slider-line"></div>
</div>
<input type="range" class="ba-slider-range" min="0" max="100" value="50" aria-label="Before After Slider">
</div>
</div>
<style>
.ba-slider-section {
max-width: 800px;
margin: 40px auto;
padding: 0 16px;
}
.ba-slider-title {
text-align: center;
margin-bottom: 20px;
font-size: 1.5rem;
}
.ba-slider-container {
position: relative;
width: 100%;
overflow: hidden;
border-radius: 8px;
cursor: ew-resize;
user-select: none;
-webkit-user-select: none;
}
.ba-slider-image img {
display: block;
width: 100%;
height: auto;
pointer-events: none;
}
.ba-slider-after {
position: relative;
width: 100%;
}
.ba-slider-before {
position: absolute;
top: 0;
left: 0;
width: 50%;
height: 100%;
overflow: hidden;
z-index: 2;
}
.ba-slider-before img {
width: 200%;
max-width: none;
height: 100%;
object-fit: cover;
}
.ba-slider-label {
position: absolute;
bottom: 16px;
background: rgba(0, 0, 0, 0.6);
color: #fff;
padding: 4px 12px;
border-radius: 4px;
font-size: 0.85rem;
z-index: 5;
pointer-events: none;
}
.ba-label-before {
left: 12px;
}
.ba-label-after {
right: 12px;
}
.ba-slider-handle {
position: absolute;
top: 0;
left: 50%;
width: 4px;
height: 100%;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
z-index: 3;
transform: translateX(-50%);
pointer-events: none;
}
.ba-slider-line {
flex: 1;
width: 3px;
background: #fff;
box-shadow: 0 0 4px rgba(0, 0, 0, 0.4);
}
.ba-slider-circle {
width: 44px;
height: 44px;
background: #fff;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.3);
color: #333;
flex-shrink: 0;
}
.ba-slider-range {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
margin: 0;
opacity: 0;
z-index: 4;
cursor: ew-resize;
-webkit-appearance: none;
appearance: none;
}
.ba-slider-range::-webkit-slider-thumb {
-webkit-appearance: none;
width: 44px;
height: 100%;
cursor: ew-resize;
}
@media (max-width: 768px) {
.ba-slider-section {
margin: 24px auto;
}
.ba-slider-circle {
width: 36px;
height: 36px;
}
.ba-slider-circle svg {
width: 18px;
height: 18px;
}
}
</style>
<script>
document.addEventListener('DOMContentLoaded', function () {
const containers = document.querySelectorAll('.ba-slider-container');
containers.forEach(function (container) {
const rangeInput = container.querySelector('.ba-slider-range');
const beforeLayer = container.querySelector('.ba-slider-before');
const handle = container.querySelector('.ba-slider-handle');
function updateSlider(value) {
const percentage = value + '%';
beforeLayer.style.width = percentage;
handle.style.left = percentage;
}
// range input によるスライダー操作
rangeInput.addEventListener('input', function () {
updateSlider(this.value);
});
// ドラッグ操作対応
let isDragging = false;
function getPositionX(e) {
if (e.touches && e.touches.length > 0) {
return e.touches[0].clientX;
}
return e.clientX;
}
function handleMove(e) {
if (!isDragging) return;
e.preventDefault();
const rect = container.getBoundingClientRect();
const x = getPositionX(e) - rect.left;
const percentage = Math.max(0, Math.min(100, (x / rect.width) * 100));
rangeInput.value = percentage;
updateSlider(percentage);
}
function startDrag(e) {
isDragging = true;
handleMove(e);
}
function stopDrag() {
isDragging = false;
}
// マウスイベント
container.addEventListener('mousedown', startDrag);
document.addEventListener('mousemove', handleMove);
document.addEventListener('mouseup', stopDrag);
// タッチイベント
container.addEventListener('touchstart', startDrag, { passive: false });
document.addEventListener('touchmove', handleMove, { passive: false });
document.addEventListener('touchend', stopDrag);
// 初期表示
updateSlider(50);
});
});
</script>
テーマエディターからセクション設定を行えるよう、以下の schema を Liquid ファイルの末尾に追加します。
{% schema %}
{
"name": "Before/After Slider",
"settings": [
{
"type": "text",
"id": "title",
"label": "セクションタイトル",
"default": "ビフォーアフター"
},
{
"type": "image_picker",
"id": "before_image",
"label": "Before 画像"
},
{
"type": "image_picker",
"id": "after_image",
"label": "After 画像"
},
{
"type": "text",
"id": "before_label",
"label": "Before ラベル",
"default": "Before"
},
{
"type": "text",
"id": "after_label",
"label": "After ラベル",
"default": "After"
}
],
"presets": [
{
"name": "Before/After Slider"
}
]
}
{% endschema %}
上記のコードをすべて1つの .liquid ファイルにまとめて sections/before-after-slider.liquid として保存すれば、テーマエディターの「セクションを追加」から「Before/After Slider」を選択して利用できるようになります。
各アプリの料金プランを一覧で整理します。
無料プランが用意されているアプリもありますが、スライダー作成数や機能に制限がある場合が多いです。本格的に活用するのであれば、有料プランへの移行を検討しましょう。最も低価格な有料アプリは Ultimate Before/After Widget の $1.50/月です。
Shopify で画像ビフォーアフタースライダーアプリを利用する際、日本語でのサポートを受けられるかどうかは重要なポイントです。
日本語でのサポートに対応しているのは「シンプル画像ビフォーアフター|お手軽イメージ前後比較」のみです。英語でのやり取りに不安がある方や、導入時にサポートを頼りたい方には、日本語対応アプリを選ぶことをおすすめします。
数あるビフォーアフタースライダーアプリの中で、総合的な使いやすさを重視するなら「シンプル画像ビフォーアフター|お手軽イメージ前後比較」をおすすめします。
その理由は以下の通りです。
迷ったらまずは「シンプル画像ビフォーアフター」を試してみてください。
シンプル画像ビフォーアフター|お手軽イメージ前後比較 のインストールはこちら
この記事では、Shopify で画像ビフォーアフター(Before After)スライダーを導入する方法として、各種アプリの比較紹介とコーディングによる実装方法を解説しました。
アプリを使えば、ノーコードで手軽にビフォーアフタースライダーを設置でき、商品の変化を視覚的に訴求することが可能です。特に日本語サポートや使いやすさを重視する方には「シンプル画像ビフォーアフター|お手軽イメージ前後比較」がおすすめです。
一方、コーディングに慣れている方であれば、Liquid テーマに直接カスタムコードを追加することで、アプリに依存せず自由度の高いスライダーを実装することもできます。
ストアの運用方針や技術力に合わせて、最適な導入方法を選択してください。画像ビフォーアフタースライダーを活用して、商品の魅力をより効果的に伝えていきましょう。