Hong Kong Skyline at Night
Monument Valley

Variations on this technique are fairly common on the web, so I decided to code my own version as a short lesson. The examples above show two versions of the effect: an image cross-fade and a scroll, both with captions that slide into place. The markup looks like this:

<div id="sliding-container">
	<figure>
		<img src="hong-kong-skyline.jpg" alt>
		<figcaption>Hong Kong Skyline at Night</figcaption>
	</figure>
	<figure>
		<img src="monument-valley-panorama.jpg" alt style="position: absolute">
		<img src="monument-valley-mittens-panorama.jpg" alt>
		<figcaption>Monument Valley</figcaption>
	</figure>
</div>

Both <figure> elements have relative positioning; overflow is set to hide anything outside the immediate area of the image after the captions are positioned, and the figure elements are set side-by-side using flexbox:


div#sliding-container { display: flex; }
div#sliding-container figure {
	margin: 0; 
	position: relative; 
	flex: 1;
	font-size: 0; 
	overflow: hidden; 
}

The captions are provided with an rgba background color, while using position: absolute:

div#sliding-container figure figcaption { 
	background: rgba(0,0,0,0.3);
	color: #fff;
	padding: .3rem;
	position: absolute;
	top: -2rem;
	transition: .6s;
}

Making the captions lower when the user hovers over an image is made possible by attacing a :hover pseudo-selector to the <figure> that changes the position of the descendant <figcaption>.

div#sliding-container figure:hover figcaption { 
	transform: translateY(2rem);
}

Next we want to animate the images inside each <figure>. First, we need to set them up correctly:

div#sliding-container figure img { 
	max-width: 100%;
	transition: 2.4s linear;
}
div#sliding-container figure:first-of-type img {
	max-width: 133%;
}

The first image, which is larger than its container, must move right to left:

div#sliding-container figure:first-of-type:hover img { 
	transform: translateX(-24%); 
}

Because they are absolutely positioned, the images of Monument Valley will appear one top of the other. We want to fade out the first image on hover:

div#sliding-container figure:last-of-type:hover img:nth-child(1) { 
	opacity: 0;
}

Panoramic photograph of Hong Kong by Gary Elsasser; photographs of Monument Valley by Alex Proimos and Ernesto Andrade,.

Enjoy this piece? I invite you to follow me at twitter.com/dudleystorey to learn more.
Check out the CodePen demo for this article at https://codepen.io/dudleystorey/pen/KpRJoL