Image comparison slider with pure CSS

As a few of you know, I have been spending a good part of this year writing a book for O’Reilly called “CSS Secrets” (preorder here!). I wanted to include a “secret” about the various uses of the resize property, as it’s one of my favorite underdogs, since it rarely gets any love. However, just mentioning the typical use case of improving the UX of text fields didn’t feel like enough of a secret at all. The whole purpose of the book is to get authors to think outside the box about what’s possible with CSS, not to recite widely known applications of CSS features. So I started brainstorming: What else could we do with it?

Then I remembered Dudley’s awesome Before/After image slider from a while ago. While I loved the result, the markup isn’t great and it requires scripting. Also, both images are CSS backgrounds, so for a screen reader, there are no images there. And then it dawned on me: What if I overlaid a <div> on an image and made it horizontally resizable through the resize property? I tried it, and as you can see below, it worked!

The good parts:

  • More semantic markup (2 images & 2 divs). If object-fit was widely supported, it could even be just one div and two images.
  • No JS
  • Less CSS code

Of course, few things come with no drawbacks. In this case:

  • One big drawback is keyboard accessibility. Dudley’s demo uses a range input, so it’s keyboard accessible by design.
  • You can only drag from the bottom right corners. In Dudley’s demo, you can click at any point in the slider. And yes, I did try to style ::webkit-resizer and increase its size so that at least it has smoother UX in Webkit. However, no matter what I tried, nothing seemed to work.

Also, none of the two seems to work on mobile.

It might not be perfect, but I thought it’s a pretty cool demo of what’s possible with the resize property, as everybody seems to only use it in textareas and the like, but its potential is much bigger.

And now if you’ll excuse me, I have a chapter to write 😉

Edit: It looks like somebody figured out a similar solution a few months ago, which does manage to make the resizer full height, albeit with less semantic HTML and more flimsy CSS. The main idea is that you use a separate element for the resizing (in this case a textarea) with a height of 15px = the height of the resizer. Then, they apply a scaleY() transform to stretch that 15px to the height of the image. Pretty cool! Unfortunately, it requires hardcoding the image size in the CSS.

  • David Karger

    Neat! But for some reason it only works on chrome, not ff?

    • Lea Verou

      It works on FF here! Which version/OS?

      PS: Wow, really honored you commented on my blog!

      • David Karger

        Interesting—just checked and found I was running ff30 (windows). Updated to ff31 and now it works.

        • Heracles

          I confirm it doesn’t work on FF30, but works on the latest version.

        • Lea Verou

          I just checked FF30 through Browserstack and it appears you’re right! The reason seems to be that the pseudo-element for the styled resizer is capturing pointer events so they never get through to the actual resizer.

          It could be fixed by adding pointer-events: none; to the pseudo-element, but then cursor: ew-resize won’t work on it either (since it’s now invisible to the mouse) so it would need to be added to the whole overlay image, which is misleading UX, as it can’t be resized everywhere, but only from the bottom right corner.

          Since Firefox applies cursor: ew-resize to the resizer anyway, the ideal solution would be to only apply pointer-events: none to FF < 30, but that would require hacks or browser sniffing, so I’m not that fond of it.

      • Beben Koben

        I do not know about CSS is correct, but I am a reckless 😀
        Here work on Firefox 18.0.1

        Hihihi 😀

    • renekreijveld

      Does not work on ipad. Anyone can confirm?

  • Alexander Futekov

    Stunningly great idea, I love how simple it is.

    But wouldn’t 2 divs and 2 images be better – ? No need for object-fit.

  • TNK

    I guesss, one more drawback is that one image is in HTML, and another in CSS.

    • Lea Verou

      That was intentional. I thought it’s much better to have at least one of the images in the HTML, so it could be picked up by screen readers and the like. Somebody else in the comments even offered a solution with both images in the HTML.

  • Matthew Felgate

    This is awesome.

  • MaxArt

    Ok, this is very cool.

    May I suggest to stylize the resize handler in those browsers that support it?

    For example, using `::-webkit-resizer` in Chrome/Safari.

    • Lea Verou

      If you read the comments, I tried using ::-webkit-resizer to make the handler bigger in WebKIt/Blink. It seems that it only allows very basic styling. Even cursor didn’t work! Overlaying a pseudo-element on the resizer seems to work fine everywhere.

  • Pingback: Tweet Parade (no.30 July 2014) - Best Articles of Last Week | gonzoblog

  • Pingback: Collective #126 » CSS 3 & HTML 5 Links und Infos

  • Pingback: Collective #126 |

  • 一丝
    • 哥特复兴


  • Pingback: 10 hilfreiche Tutorials und Quellen für Webentwickler und -designer (Teil 4) » t3n

  • Pingback: Collective #126 | Daniele Milana

  • Tiago Celestino

    Oo amazing!!

  • Ahmad Alfy

    wow. That’s supereb!

    edit: brb, gotta preorder my copy.

  • Pingback: WordPress Magic - TEN THINGS TRENDING Jul 30 2014 |

  • Hjoaco Mg

    Perfect in chromium, firefox, midori and opera on Manjaro Openbox 😀

  • Bruno Škvorc

    Confirming that it doesn’t work on FF30

  • Ronnie_Gardocki

    This stuff is awesome! And it’s looks cool with background-blend-mode feature

    • Lea Verou

      That’s really cool!

  • TweetsOfSumit

    Didn’t know about the resize property. Cool stuff. Sadly it’s not supported on any mobile browser or Internet Explorer so i could never use it. Still cool though and I hope support will be coming sooner than later

  • Pingback: Pure CSS Image Comparison Slider | Constructs

  • Pingback: Slider de comparação de imagens com CSS puro |

  • Pingback: Collective #126 - WeBlog

  • Tom

    Awesome work. Is there a way for have the slider start in the middle and still be able to slide both ways?

  • Eugene

    Awesome but not working with bootstrap

  • Eugene

    awesome but not working with bootstrap

  • Pingback: Collective #126 | Web Design Articles From An Actual Living Web Professional

  • Pingback: Cursore di confronto immagini in CSS | Laboratorio CSS

  • Camilla Gönczi

    Is there any way to make it go both ways? I want to start with the slider in the middle but if i cant make it go left…

  • Pingback: Cartno How to Animated Image Changes with background-blend-mode