JSFiddle - React, Tailwind, and code Playground
by phloe
HTML
<div class="wrapper">
<ol>
<li class="selected"><figure>
<div class="image">
<img src="https://fillmurray.com/640/360"/>
</div>
<figcaption>Aliquam ut odio in neque facilisis efficitur.</figcaption>
</figure></li>
<li><figure>
<div class="image">
<img src="https://fillmurray.com/656/369"/>
</div>
<figcaption>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse cursus enim vitae metus interdum faucibus. Mauris at nibh congue, iaculis elit in, pulvinar ex.</figcaption>
</figure></li>
<li><figure>
<div class="image">
<img src="https://fillmurray.com/672/378"/>
</div>
<figcaption>Aenean varius leo sed orci pharetra, eu cursus nibh interdum. Praesent eget dui rhoncus, fringilla urna scelerisque, elementum sapien.</figcaption>
</figure></li>
<li><figure>
<div class="image">
<img src="https://fillmurray.com/688/387"/>
</div>
<figcaption>Aliquam quis felis vitae quam rutrum elementum. Sed in neque quam.</figcaption>
</figure></li>
<li><figure>
<div class="image">
<img src="https://fillmurray.com/704/396"/>
</div>
<figcaption>Fusce consequat egestas nunc eu feugiat. Fusce sit amet sapien vitae nibh dictum hendrerit.</figcaption>
</figure></li>
</ol>
</div>
CSS
.wrapper {
overflow: visible;
perspective: 1000px;
perspective-origin: 50% 0;
max-width: 600px;
margin: 0 auto;
background-color: #FFF;
}
ol {
margin: 0;
padding: 0;
white-space: nowrap;
font-size: 0;
transition: transform .3s ease;
transform-style: preserve-3d;
}
li {
width: 100%;
white-space: normal;
font-size: 1rem;
display: inline-block;
vertical-align: top;
transform-style: preserve-3d;
}
li .image {
transform: translateZ(-1000px) translateX(-50%);
transition: transform .3s ease;
}
.selected .image {
transform: none;
}
.selected ~ li .image {
transform: translateZ(-1000px) translateX(50%);
}
figure {
margin: 0;
}
img {
width: 100%;
height: auto;
}
.image {
position: relative;
overflow: hidden;
}
.image:after {
content: "";
display: block;
padding-bottom: 56.25%;
}
.image > * {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
figcaption {
background-color: #FFF;
padding: 20px;
opacity: 0;
transform: translateX(100%);
transition: transform .3s ease, opacity .3s ease;
}
.selected figcaption {
opacity: 1;
transform: none;
}
.selected ~ li figcaption {
pointer-events: none;
transform: translateX(-100%);
}
JavaScript
var selected = document.querySelector("li.selected");
var wrapper = document.querySelector("ol");
var width = wrapper.offsetWidth;
var items = Array.from(wrapper.getElementsByTagName("li"));
wrapper.addEventListener("click", ({ target }) => {
window.console && console.log("click", target);
var element = target.closest("li:not(.selected)");
if (element) {
selected.classList.remove("selected");
selected = element;
selected.classList.add("selected");
setOffset();
}
});
function setOffset () {
var index = items.indexOf(selected);
var offset = index * -100;
wrapper.style.transform = `translateX(${offset}%)`;
}
window.addEventListener("resize", () => {
width = wrapper.offsetWidth;
setOffset();
});