Want to visually show the impact of your campaign or a project transformation? A before-and-after slider lets users interactively compare two images by dragging a handle between them. This is ideal for showcasing renovations, climate impact, restoration projects, or design changes.
This guide explains how to implement a responsive before/after image slider using HTML, CSS, and JavaScript—all fully compatible with CamBuildr pages.
What This Slider Does
Displays two stacked images with a draggable divider.
The left image (“before”) reveals or hides as the user moves the slider.
Works on desktop and mobile (touch and mouse supported).
Step 1: Insert the HTML Block
Paste the following code into a new HTML block on your landing page:
<div class="ba-slider-container">
<div id="before-after-slider">
<div id="before-image">
<img src="BEFORE_IMAGE_URL" alt="Before" draggable="false" />
</div>
<div id="after-image">
<img src="AFTER_IMAGE_URL" alt="After" draggable="false" />
</div>
<div id="resizer"></div>
</div>
</div>
Replace BEFORE_IMAGE_URL and AFTER_IMAGE_URL with the actual links to your images. Use images of equal dimensions for the best result.
Step 2: Add the CSS for Layout and Styling
In the same block (or a global style block), include this CSS to style and animate the slider:
<style>
.ba-slider-container {
width: 100%;
max-width: 100%;
margin: 0 auto;
}
#before-after-slider {
position: relative;
overflow: hidden;
width: 100%;
max-width: 800px;
margin: 0 auto;
}
#before-after-slider img {
display: block;
width: 100%;
height: auto;
pointer-events: none;
}
#after-image {
position: relative;
z-index: 1;
}
#before-image {
position: absolute;
top: 0;
left: 0;
width: 50%;
height: 100%;
overflow: hidden;
z-index: 2;
}
#resizer {
position: absolute;
top: 0;
left: 50%;
width: 4px;
height: 100%;
background: white;
z-index: 3;
cursor: ew-resize;
}
#resizer:after {
content: '';
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 20px;
height: 20px;
background: white;
border-radius: 50%;
border: 2px solid #ccc;
}
#before-after-slider,
#before-after-slider * {
user-select: none;
-webkit-user-drag: none;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
}
</style>
Step 3: Add the JavaScript Functionality
Below the HTML and CSS in the same block, paste the following script:
<script>
const slider = document.getElementById('before-after-slider');
const before = document.getElementById('before-image');
const beforeImg = before.querySelector('img');
const resizer = document.getElementById('resizer');
let active = false;
function syncWidth() {
beforeImg.style.width = slider.offsetWidth + 'px';
}
document.addEventListener('DOMContentLoaded', syncWidth);
window.addEventListener('resize', syncWidth);
// Mouse events
resizer.addEventListener('mousedown', () => active = true);
document.body.addEventListener('mouseup', () => active = false);
document.body.addEventListener('mouseleave', () => active = false);
document.body.addEventListener('mousemove', (e) => {
if (!active) return;
slideIt(e.pageX);
e.preventDefault();
});
// Touch events
resizer.addEventListener('touchstart', () => active = true);
document.body.addEventListener('touchend', () => active = false);
document.body.addEventListener('touchcancel', () => active = false);
document.body.addEventListener('touchmove', (e) => {
if (!active) return;
slideIt(e.touches[0].pageX);
e.preventDefault();
});
function slideIt(x) {
const rect = slider.getBoundingClientRect();
let offset = x - rect.left;
offset = Math.max(0, Math.min(offset, slider.offsetWidth));
before.style.width = offset + "px";
resizer.style.left = offset + "px";
}
// Animate in when visible
const observer = new IntersectionObserver(entries => {
entries.forEach(entry => {
if (entry.isIntersecting) {
const half = slider.offsetWidth / 2;
before.style.transition = "width 1s ease";
resizer.style.transition = "left 1s ease";
before.style.width = half + "px";
resizer.style.left = half + "px";
setTimeout(() => {
before.style.transition = "";
resizer.style.transition = "";
}, 1000);
observer.unobserve(slider);
}
});
}, {
threshold: 0.5
});
observer.observe(slider);
</script>
Best Practices
Image size: Use JPG or PNG images of the same aspect ratio and resolution for best performance.
Label your images (optional): You can add “Before” and “After” labels using text overlays in image editors or add <div> labels with absolute positioning.
Mobile fallback: Touch sliding is supported, but a tap-to-reveal option can be added if needed.
Common Use Cases
Before/after shots from field projects
Visual impact of a policy or initiative
Timeline visuals (past vs. current status)
“What we found” vs. “What we changed”