Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@emerham
Last active December 6, 2022 18:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save emerham/7f821743c553461f303298c1812f6de9 to your computer and use it in GitHub Desktop.
Save emerham/7f821743c553461f303298c1812f6de9 to your computer and use it in GitHub Desktop.
HTML Before and After with css and js
.before-and-after__main {
width: 100%;
max-width: max-content;
}
.before-and-after__wrapper {
position: relative;
user-select: none;
overflow: hidden;
width: 100%;
}
.before-and-after__before {
position: absolute;
top: 0;
left: 0;
width: 50%;
height: 100%;
overflow: hidden;
}
.before-and-after__before img {
max-width: unset !important;
}
.before-and-after__after {
width: max-content;
}
.before-and-after__after img {
max-width: unset !important;
}
.before-and-after__scroller {
position: absolute;
top: calc(50% - 50px);
left: calc(50% - 50px);
width: 100px;
height: 100px;
cursor: pointer;
}
<html>
<body>
<main>
<div class="before-and-after__main">
<div class="before-and-after__wrapper">
<div class="before-and-after__before"><img alt="" class="content-image" draggable="false" src="https://farm2.staticflickr.com/1638/26145024230_06acd55d1b_b.jpg" /></div>
<div class="before-and-after__scroller"><svg class="scroller__thumb" height="100" viewbox="0 0 100 100" width="100" xmlns="http://www.w3.org/2000/svg"><polygon points="0 50 37 68 37 32 0 50" style="fill:#fff"></polygon><polygon points="100 50 64 32 64 68 100 50" style="fill:#fff"></polygon></svg></div>
<div class="before-and-after__after"><img alt="" class="content-image" draggable="false" src="https://farm2.staticflickr.com/1663/25814974803_d4c55ff708_b.jpg" /></div>
</div>
</div>
</main>
</body>
</html>
// I hope this over-commenting helps. Let's do this!
// Let's use the 'active' variable to let us know when we're using it
let active = false;
// First we'll have to set up our event listeners
// We want to watch for clicks on our scroller
document.querySelectorAll('.before-and-after__wrapper').forEach(beforAndAfterWrapper => {
beforAndAfterWrapper.addEventListener('mousemove', event => {
if (!active) return;
let x = event.pageX;
let scrollerParent = event.target.closest('.before-and-after__wrapper');
if (scrollerParent) {
x -= scrollerParent.getBoundingClientRect().left;
scrollIt(scrollerParent, x);
}
});
beforAndAfterWrapper.addEventListener('mouseleave', beforeAndAfterMouseLeave);
});
document.querySelectorAll('.before-and-after__scroller').forEach(scroller => {
scroller.addEventListener('mousedown', beforeAndAfterMouseEnter);
scroller.addEventListener('mouseup', beforeAndAfterMouseLeave);
scroller.addEventListener('touchstart', beforeAndAfterMouseEnter);
scroller.addEventListener('toucheend', beforeAndAfterMouseLeave);
scroller.addEventListener('touchecancel', beforeAndAfterMouseLeave);
});
/**
* Function to perform the reveal.
*
* @param {HTMLElement} beforeAndAfterWrapper an html element that should be the wrapper.
* @param {number} amount the amount of pixels to move everything around.
*/
function scrollIt(beforeAndAfterWrapper, amount) {
let transform = Math.max(0, (Math.min(amount, beforeAndAfterWrapper.offsetWidth)));
beforeAndAfterWrapper.querySelector('.before-and-after__before').style.width = transform + "px";
beforeAndAfterWrapper.querySelector('.before-and-after__scroller').style.left = transform - 50 + "px";
}
/**
* Trigger that the mouse has left the area.
* @param {EventTarget} mouseEvent The event target.
*/
function beforeAndAfterMouseLeave(mouseEvent) {
active = false;
const scrollerIsNested = mouseEvent.target.querySelector('.before-and-after__scroller');
if (scrollerIsNested) {
scrollerIsNested.classList.remove('scrolling');
}
mouseEvent.target.classList.remove('scrolling');
}
/**
* Trigger that the mouse has entered and started moving.
* @param {EventTarget} mouseEvent The event target item.
*/
function beforeAndAfterMouseEnter(mouseEvent) {
active = true;
mouseEvent.target.classList.add('scrolling');
}
// Let's set our opening state based off the width,
// we want to show a bit of both images so the user can see what's going on
window.addEventListener('load', () => {
// Get Every element that might be the before and after wrapper.
document.querySelectorAll('.before-and-after__wrapper').forEach(element => {
// use the elements actual with to start in the middle.
let wrapperWidth = parseFloat(window.getComputedStyle(element).width);
scrollIt(element, wrapperWidth / 2);
});
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment