Introduction
Creating an interactive before-after slider is a great way to showcase comparisons, such as image transformations, design changes, or project progressions. In this tutorial, we'll walk through building a responsive and interactive before-after slider using HTML, CSS, and JavaScript. Additionally, we'll explore how to implement the same functionality using React.js for more dynamic applications.
HTML Structure
The foundation of our slider consists of a container that holds the before and after images, navigation arrows, and the slider handle itself. Here's the basic HTML structure:
1<div class="container-wrapper">2 <div class="arrow arrow-left" id="arrow-left"><</div>3 <div class="slider-container" id="slider-container">4 <div class="after-image" style="background-image: url('after.png');">5 <span class="label after">After</span>6 </div>7 <div8 class="before-image"9 id="before-image"10 style="background-image: url('before.png');"11 >12 <span class="label before">Before</span>13 </div>14 <div class="slider" id="slider"></div>15 </div>16 <div class="arrow arrow-right" id="arrow-right">></div>17</div>
CSS Styling
The CSS is responsible for positioning the images, styling the slider handle, and ensuring responsiveness across different screen sizes. Here's the complete CSS:
1.slider-container {2 position: relative;3 height: 500px;4}5.slider-container .label {6 position: absolute;7 bottom: 10px;8 font-weight: 300;9 font-size: 0.75em;10 pointer-events: none;11 user-select: none;12}13.label.before {14 left: 10px !important;15}16.label.after {17 right: 10px !important;18}19.before-image,20.after-image {21 position: absolute;22 width: 100%;23 height: 500px;24 background-size: cover;25 background-position: center;26 top: 0;27 left: 0;28 display: flex;29 justify-content: center;30 align-items: center;31 color: white;32 font-size: 24px;33 font-weight: bold;34}35.slider {36 position: absolute;37 top: 0;38 bottom: 0;39 left: 50%; /* Initial position of the slider */40 width: 5px;41 height: 500px;42 background-color: white; /* Example color */43 cursor: ew-resize;44 z-index: 2;45 transform: translateX(-50%);46}47.arrow {48 width: 30px;49 height: 30px;50 display: flex;51 justify-content: center;52 align-items: center;53 cursor: pointer;54 z-index: 3;55 user-select: none;56}57/* Prevent text/image selection */58.arrow img {59 user-select: none;60 pointer-events: none;61}62.arrow.arrow-left {63 margin-right: 10px;64}65.arrow.arrow-right {66 margin-left: 10px;67}
JavaScript Functionality
JavaScript adds interactivity to our slider, allowing users to drag the slider handle and click the navigation arrows to adjust the slider position. Here's the complete JavaScript code:
1document.addEventListener("DOMContentLoaded", function () {2 const sliderContainer = document.getElementById("slider-container");3 const beforeImage = document.getElementById("before-image");4 const slider = document.getElementById("slider");5 const arrowLeft = document.getElementById("arrow-left");6 const arrowRight = document.getElementById("arrow-right");7 let isDragging = false;8 let sliderPosition = 50;9
10 const updateSlider = (position) => {11 slider.style.left = `${position}%`;12 beforeImage.style.clipPath = `inset(0px calc(100% - ${position}%) 0px 0px)`;13 };14
15 const handleMouseDown = () => {16 isDragging = true;17 };18 const handleMouseUp = () => {19 isDragging = false;20 };21 const handleMouseMove = (e) => {22 if (!isDragging) return;23 const rect = sliderContainer.getBoundingClientRect();24 let position = ((e.clientX - rect.left) / rect.width) * 100;25 position = Math.max(2.5, Math.min(position, 97.5));26 sliderPosition = position;27 updateSlider(sliderPosition);28 };29
30 const handleArrowClick = (direction) => {31 sliderPosition =32 direction === "left" ? sliderPosition - 2 : sliderPosition + 2;33 sliderPosition = Math.max(2.5, Math.min(sliderPosition, 97.5));34 updateSlider(sliderPosition);35 };36
37 slider.addEventListener("mousedown", handleMouseDown);38 window.addEventListener("mousemove", handleMouseMove);39 window.addEventListener("mouseup", handleMouseUp);40 arrowLeft.addEventListener("click", () => handleArrowClick("left"));41 arrowRight.addEventListener("click", () => handleArrowClick("right"));42});
React.js Implementation
While the plain JavaScript approach is effective, integrating the slider into a React.js application allows for better state management and reusability. Below is a React component that replicates the functionality of our before-after slider.
1import React, { useState, useRef, useEffect } from "react";2import "./BeforeAfterSlider.css"; // Ensure you include the CSS styles3import BeforeImg from "./before.png";4import AfterImg from "./after.png";5
6const BeforeAfterSlider = () => {7 let beforeImage = BeforeImg;8 let afterImage = AfterImg;9 const [sliderPosition, setSliderPosition] = useState(50);10 const containerRef = useRef(null);11 const isDragging = useRef(false);12
13 const handleMouseDown = () => {14 isDragging.current = true;15 };16
17 const handleMouseUp = () => {18 isDragging.current = false;19 };20
21 const handleMouseMove = (e) => {22 if (!isDragging.current) return;23 const rect = containerRef.current.getBoundingClientRect();24 let position = e.clientX - rect.left;25 position = Math.max(2.5, Math.min(position, rect.width - 2.5));26 setSliderPosition((position / rect.width) * 100);27 };28
29 useEffect(() => {30 window.addEventListener("mousemove", handleMouseMove);31 window.addEventListener("mouseup", handleMouseUp);32 return () => {33 window.removeEventListener("mousemove", handleMouseMove);34 window.removeEventListener("mouseup", handleMouseUp);35 };36 }, []);37
38 const handleArrowClick = (direction) => {39 setSliderPosition((prev) => {40 const newPos = direction === "left" ? prev - 2 : prev + 2;41 return Math.max(2.5, Math.min(newPos, 97.5));42 });43 };44
45 return (46 <div className="container-wrapper">47 <div48 className="arrow arrow-left"49 onClick={() => handleArrowClick("left")}50 >51 <52 </div>53 <div className="slider-container" ref={containerRef}>54 <div55 className="after-image"56 style={{ backgroundImage: `url('${afterImage}')` }}57 >58 <span className="label after">After</span>59 </div>60 <div61 className="before-image"62 style={{63 backgroundImage: `url('${beforeImage}')`,64 clipPath: `inset(0px calc(100% - ${sliderPosition}%) 0px 0px)`,65 }}66 >67 <span className="label before">Before</span>68 </div>69 <div70 className="slider"71 style={{ left: `${sliderPosition}%` }}72 onMouseDown={handleMouseDown}73 ></div>74 </div>75 <div76 className="arrow arrow-right"77 onClick={() => handleArrowClick("right")}78 >79 >80 </div>81 </div>82 );83};84
85export default BeforeAfterSlider;
Notes:
- State Management:
sliderPosition
state controls the position of the slider. - Event Handling: Mouse events are managed to handle dragging functionality.
- Props:
beforeImage
andafterImage
are passed as props for flexibility. - Styling: Ensure that the CSS from the earlier section is included for proper styling.
Usage Example:
1import React from "react";2import BeforeAfterSlider from "./BeforeAfterSlider";3
4const App = () => {5 return (6 <div>7 <h1>Before-After Slider Example</h1>8 <BeforeAfterSlider />9 </div>10 );11};12
13export default App;
Example renderer of the solution
Controlling Slider Behavior
To enhance the slider's functionality and user experience, consider implementing the following:
- Responsive Adjustments: Ensure the slider adjusts smoothly across various screen sizes using CSS media queries.
- Touch Support: Enhance mobile usability by adding touch event listeners, allowing users to swipe the slider on touch-enabled devices.
- Animations: Add CSS transitions to the slider handle and image clips for smoother movements.
- Accessibility: Incorporate keyboard controls and ARIA labels to make the slider accessible to all users.
Example of Adding CSS Transitions:
1.slider {2 transition: left 0.3s ease;3}4.before-image {5 transition: clip 0.3s ease;6}
Conclusion
In this tutorial, we've built a fully functional before-after slider using both plain JavaScript and React.js. This component can be a valuable addition to portfolios, product showcases, and many other applications where visual comparisons are essential. Feel free to customize and extend the slider's functionality to fit your project's needs. Happy coding!
Comments
You must be logged in to comment.
Loading comments...