A simple and clean image comparison slider, fully responsive and touch ready made with css and jquery.
A Pen by Andreas Borgen on CodePen.
A simple and clean image comparison slider, fully responsive and touch ready made with css and jquery.
A Pen by Andreas Borgen on CodePen.
| <h1>Image Comparison Slider</h1> | |
| <h3> Compare images and any html content</h3> | |
| <div class="comparison-container"> | |
| <img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/751678/marioPhoto-2.jpg" alt="marioPhoto 2" /> | |
| <div class="caption">And I am the <strong>after</strong> image.</div> | |
| <div class="comparison-lhs"> | |
| <img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/751678/marioPhoto-1.jpg" alt="marioPhoto 1" /> | |
| <div class="caption">I am the <strong>before</strong> image.</div> | |
| </div> | |
| </div> | |
| <h3> Compare more than two images</h3> | |
| <div class="comparison-container"> | |
| <img src="https://programming.enthuses.me/assets/codepen/sin-city/scene-comp-3.jpg" alt="" /> | |
| <img class="comparison-lhs" data-comparison-splitter="80%" src="https://programming.enthuses.me/assets/codepen/sin-city/scene-comp-2.jpg" alt="" /> | |
| <img class="comparison-lhs" data-comparison-splitter="60%" src="https://programming.enthuses.me/assets/codepen/sin-city/scene-comp-1.jpg" alt="" /> | |
| </div> |
| (function() { | |
| "use strict"; | |
| function $$(selector) { | |
| return Array.from(document.querySelectorAll(selector)); | |
| } | |
| function syncSize(master, slave) { | |
| slave.style.width = master.clientWidth + 'px'; | |
| } | |
| function getMouseX(parent, e) { | |
| const bounds = parent.getBoundingClientRect(), | |
| x = e.clientX - bounds.left; | |
| return { x, width: bounds.width }; | |
| } | |
| function initComparer(lhs) { | |
| const container = lhs.closest('.comparison-container'), | |
| splitPos = lhs.dataset.comparisonSplitter; | |
| let dragOffset; | |
| //Lock the compared element's width to the original width: | |
| window.addEventListener('load', e => syncSize(container, lhs)); | |
| window.addEventListener('resize', e => syncSize(container, lhs)); | |
| syncSize(container, lhs); | |
| //Put the compared element into a resizable wrapper: | |
| const lhsWrapper = container.appendChild(document.createElement('div')); | |
| lhsWrapper.classList.add('comparison-lhs-wrapper'); | |
| lhsWrapper.appendChild(lhs); | |
| const dragger = container.appendChild(document.createElement('div')); | |
| dragger.classList.add('comparison-dragger'); | |
| if(splitPos) { | |
| lhsWrapper.style.width = dragger.style.left = splitPos; | |
| } | |
| //Dragging magic: | |
| dragger.onmousedown = (e) => { | |
| e.preventDefault(); | |
| dragOffset = getMouseX(dragger, e); | |
| //console.log(lhs, dragOffset) | |
| }; | |
| container.addEventListener('mousemove', e => { | |
| if(dragOffset) { | |
| if(e.buttons === 1) { | |
| e.preventDefault(); | |
| const newX = getMouseX(container, e), | |
| relX = (newX.x - dragOffset.x) / newX.width; | |
| lhsWrapper.style.width = dragger.style.left = (Math.max(0, Math.min(relX, 1)) * 100) + '%'; | |
| } | |
| else { | |
| dragOffset = undefined; | |
| } | |
| } | |
| }); | |
| } | |
| function init() { | |
| $$('.comparison-lhs').forEach(initComparer); | |
| } | |
| init(); | |
| })(); |
| .comparison { | |
| &-container { | |
| position: relative; | |
| //Make sure the container doesn't stretch horizontally beyond its content: | |
| display: table; | |
| overflow: hidden; | |
| } | |
| &-lhs, &-lhs-wrapper { | |
| position: absolute; | |
| top:0; left:0; | |
| } | |
| &-lhs { | |
| //For inline elements, such as <img> | |
| display: block; | |
| max-width: none; | |
| } | |
| &-lhs-wrapper { | |
| height: 100%; | |
| width: 50%; | |
| overflow: hidden; | |
| } | |
| &-dragger { | |
| position: absolute; | |
| top:0; left:50%; | |
| width: 0; | |
| height: 100%; | |
| cursor: ew-resize; | |
| &::before { | |
| content: ''; | |
| display: block; | |
| width: .4em; | |
| height: 100%; | |
| margin-left: -.2em; | |
| background: rgba(white, .3); | |
| } | |
| &::after { | |
| $button-size: 2.2em; | |
| content: '◀ ▶'; | |
| display: block; | |
| position: absolute; | |
| top: 50%; left: 50%; | |
| width: $button-size; | |
| height: $button-size; | |
| margin: $button-size/-2; | |
| border-radius: 100%; | |
| background: white; | |
| text-align: center; | |
| line-height: $button-size; | |
| white-space: nowrap; | |
| } | |
| } | |
| } | |
| /* Page layout - not important */ | |
| body { | |
| font-family: Georgia, sans-serif; | |
| //Weird scrollbar flickering in Chrome when the page content exactly fills the page: | |
| overflow-y: scroll; | |
| } | |
| img { | |
| display: block; | |
| width: 100%; | |
| } | |
| .caption { | |
| display: inline-block; | |
| position: absolute; | |
| bottom: .5em; right: .5em; | |
| padding: .5em; | |
| background: rgba(white, .7); | |
| } | |
| .comparison-container { | |
| //width: 100%; | |
| max-width: 1000px; | |
| margin: auto; | |
| } | |
| .comparison-lhs .caption { | |
| right: auto; left: .5em; | |
| } |
Nice code, but didn't work on movil
FYI, this code does not require jQuery, you can change your
initmethod to: