Showcase your product’s transformative results with this engaging before-and-after slider. Customers can drag the slider handle to compare two images, creating an interactive experience that highlights improvements, transformations, or product benefits.
Why Use This Slider?
Visually Persuasive: Perfect for beauty, fitness, home improvement, or any product with visible results.
Easy to Customize: Upload your before/after images, adjust styling, and add optional text.
Mobile-Optimized: Works seamlessly on all devices for maximum engagement.
No Coding Needed: Simple Shopify settings with no technical skills required.
Ideal for before/after comparisons, product effectiveness proofs, and customer success stories. Increase trust and conversions with a dynamic visual demo!
- Need help implementing this? Contact a Shopify developer for professional customization and integration services to make it work perfectly for your store.
-- Shopify Schema Code --
{% schema %}
{
"name": "Before / After Slider",
"settings": [
{
"type": "header",
"content": "Slider Settings"
},
{
"type": "text",
"id": "banner_title",
"label": "Banner Title",
"default": "Clinically Proven Hair Growth"
},
{
"type": "image_picker",
"id": "bf_image",
"label": "Before Image",
"info": "Recommended size: 1200x800px"
},
{
"type": "image_picker",
"id": "af_image",
"label": "After Image",
"info": "Should match dimensions of Before Image"
},
{
"type": "checkbox",
"id": "show_badge",
"label": "Show Badges",
"default": true
},
{
"type": "checkbox",
"id": "grayscale_before",
"label": "Grayscale for Before Image",
"default": false
},
{
"type": "header",
"content": "Content Settings"
},
{
"type": "checkbox",
"id": "show_content",
"label": "Show Content",
"default": false
},
{
"type": "text",
"id": "ba_heading",
"label": "Heading",
"default": "Transformation Results"
},
{
"type": "richtext",
"id": "ba_content",
"label": "Content",
"default": "<p>See the amazing results our customers have achieved with our product.</p>"
}
],
"presets": [
{
"name": "Before / After Slider",
"category": "Image"
}
]
}
{% endschema %}
-- Shopify Liquid Code --
{% assign unique_id = 'custom_ba_slider_' | append: section.id %}
<div class="page-width container">
<main class="custom_ba_main {{ unique_id }}">
{% if section.settings.banner_title != blank %}
<h2 class="banner-title">{{ section.settings.banner_title }}</h2>
{% endif %}
<div class="custom_ba_container custom_before_after">
<div class="custom_image_container">
<div class="custom_before_img">
{% if section.settings.bf_image != blank %}
<img decoding="async"
class="custom_image_before custom_slider_image"
src="{{ section.settings.bf_image | image_url: width: 1200 }}"
alt="{{ section.settings.bf_image.alt | escape }}"
width="{{ section.settings.bf_image.width }}"
height="{{ section.settings.bf_image.height }}"
loading="lazy"
>
{% else %}
{{ 'image' | placeholder_svg_tag: 'placeholder-svg' }}
{% endif %}
<span
class="custom_before_badge custom_ba_badge"
style="{% unless section.settings.show_badge %}display: none;{% endunless %}"
>Before</span
>
</div>
<div class="custom_after_img">
{% if section.settings.af_image != blank %}
<img decoding="async"
class="custom_image_after custom_slider_image"
src="{{ section.settings.af_image | image_url: width: 1200 }}"
alt="{{ section.settings.af_image.alt | escape }}"
width="{{ section.settings.af_image.width }}"
height="{{ section.settings.af_image.height }}"
loading="lazy"
>
{% else %}
{{ 'image' | placeholder_svg_tag: 'placeholder-svg' }}
{% endif %}
<span class="custom_after_badge custom_ba_badge" style="{% unless section.settings.show_badge %}display: none;{% endunless %}"
>After</span
>
</div>
</div>
<input
type="range"
min="0"
max="100"
value="50"
aria-label="Percentage of before photo shown"
class="custom_ba_slider"
>
<div class="custom_slider_line" aria-hidden="true"></div>
<div class="custom_slider_button" aria-hidden="true">
<svg
xmlns="http://www.w3.org/2000/svg"
width="30"
height="30"
fill="currentColor"
viewBox="0 0 256 256"
>
<rect width="256" height="256" fill="none"></rect>
<line
x1="128"
y1="40"
x2="128"
y2="216"
fill="none"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="16"
></line>
<line
x1="96"
y1="128"
x2="16"
y2="128"
fill="none"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="16"
></line>
<polyline class="custom_before_arrow"
points="48 160 16 128 48 96"
fill="none"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="16"
></polyline>
<line
x1="160"
y1="128"
x2="240"
y2="128"
fill="none"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="16"
></line>
<polyline class="custom_after_arrow"
points="208 96 240 128 208 160"
fill="none"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="16"
></polyline>
</svg>
</div>
</div>
{% if section.settings.show_content %}
<div class="custom_ba_container custom_before_after_content">
{% if section.settings.ba_heading != blank %}
<div class="custom_before_after_heading">
<h3>{{ section.settings.ba_heading }}</h3>
</div>
{% endif %}
{% if section.settings.ba_content != blank %}
<div class="custom_before_after_paragraph">
{{ section.settings.ba_content }}
</div>
{% endif %}
</div>
{% endif %}
</main>
</div>
-- CSS Code --
<style>
.custom_ba_main {
display: flex;
flex-direction: column;
align-items: center;
gap: 30px;
padding: 0 1rem;
max-width: 1325px;
width: 100%;
margin: 0 auto;
}
.banner-title {
text-align: center;
width: 100%;
}
.custom_ba_container {
position: relative;
overflow: hidden;
width: 100%;
max-width: 1200px;
--position: 50%;
}
.custom_image_container {
display: flex;
position: relative;
width: 100%;
height: auto;
aspect-ratio: {{ section.settings.bf_image.aspect_ratio | default: 1 }};
}
.custom_before_img,
.custom_after_img {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
overflow: hidden;
}
.custom_before_img {
width: var(--position);
z-index: 2;
}
.custom_slider_image {
width: 100%;
height: 100%;
object-fit: cover;
object-position: center;
display: block;
}
.custom_image_before {
{% if section.settings.grayscale_before %}filter: grayscale(100%);{% endif %}
}
.custom_before_badge,
.custom_after_badge {
position: absolute;
bottom: 15px;
background: #fff;
padding: 5px 10px;
border-radius: 5px;
color: #000;
z-index: 3;
font-weight: bold;
}
.custom_before_badge {
left: 15px;
}
.custom_after_badge {
right: 15px;
}
.custom_ba_slider {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
margin: 0;
opacity: 0;
cursor: pointer;
z-index: 4;
}
.custom_slider_line {
position: absolute;
top: 0;
bottom: 0;
left: var(--position);
width: 2px;
background-color: #fff;
transform: translateX(-50%);
z-index: 2;
pointer-events: none;
}
.custom_slider_button {
position: absolute;
top: 50%;
left: var(--position);
transform: translate(-50%, -50%);
background-color: #fff;
color: #000;
padding: 8px;
border-radius: 50%;
display: grid;
place-items: center;
box-shadow: 0 1px 3px rgba(0,0,0,0.3);
z-index: 3;
pointer-events: none;
}
.custom_slider_button svg {
display: block;
}
.custom_before_after_content {
text-align: center;
padding: 20px 0;
}
@media (max-width: 768px) {
.custom_ba_main {
padding: 0 15px;
}
.custom_before_badge,
.custom_after_badge {
font-size: 12px;
padding: 3px 6px;
}
}
</style>
-- Java Script Code --
<script>
document.addEventListener('DOMContentLoaded', function() {
const sliders = document.querySelectorAll('.custom_before_after');
sliders.forEach(slider => {
const sliderInput = slider.querySelector('.custom_ba_slider');
sliderInput.addEventListener('input', function(e) {
slider.style.setProperty('--position', `${e.target.value}%`);
});
// Initialize position
slider.style.setProperty('--position', '50%');
});
});
</script>
Key Features:
Interactive Slider: Users can drag to compare before/after images.
Customizable: Add titles, badges (“Before”/”After”), and toggle grayscale for the “Before” image.
Responsive: Works on mobile and desktop with proper image scaling.
Optional Content: Add headings and descriptive text below the slider.
Styling: Clean design with a draggable handle and smooth transitions.
