Sometimes it's funny to revisit old ideas and components, you did a long time ago!
I once did an "Image Compare"-component, with one image defined in a regular <img>-tag, one as background-image, a <div> for the draggable control — and a good chunk of JavaScript to handle the functionality.
Looking through old code during a cleanup, I stumbled across this component and thought about what I'd change, if I were to make a "2021 version".
First, I'd replace the <div> with an <input type="range"> for the draggable component. The oninput-event should update a single CSS Custom Property, setting a --value-property on the parentNode, so other children can access the value as well:
Like this:
<input type="range" oninput="this.parentNode.style.setProperty('--value', `${this.value}%`)">
The images should be two regular <img>-tags, and the --value should be used to update two clip-path's:
.c-compare__left {
  clip-path: polygon(0% 0%, var(--value) 0%, var(--value) 100%, 0% 100%);
}
.c-compare__right {
  clip-path: polygon(100% 0%, var(--value) 0%, var(--value) 100%, 100% 100%);
}
And that's the core of it!
A fully functional "Image Compare"-component in one line of JavaScript and two dynamic CSS clip-path: polygon().
The rest is just styling.
Accessibility
You get accessibility for free, since the <input type="range"> is focusable, and navigable with the arrow-keys. Set the :focus-style in CSS.
Demo
Thanks for reading!
              
    
Top comments (4)
Genial!
Smart! Thanks for sharing!
What about browser compatibility?
All except IE