Categories:

A pure CSS Before and After image effect

Updated: May 27th, 15

In this tutorial we'll see how some careful stacking of two images in CSS can make way for a quick "before" and "after" image effect, whereby moving the mouse over the image container peels back one image to reveal another. You may have seen such an effect implemented using JavaScript before, though in the brave new world of CSS3, a little ingenuity goes a long way.

Move on mouse over the below image:

The above demo consists of a "before" and "after" image, with the only difference between the two being the color of the wall. Such images are great candidates to be stacked together and viewed in such a manner, by theatrically highlighting what's different between them.

Markup and CSS

Lets start with the markup for the before/after effect, which consists of an outer container plus two inner DIVs, to house the two images, respectively:

HTML Markup
<div class="beforeandafter">

	<div class="before">
	<img src="wallbefore.jpg" />
	</div>

	<div class="after">
	<img src="wallafter.jpg" />
	</div>

</div>

First, we style the outer "beforeandafter" container so it's relatively positioned and with fixed dimensions:

"beforeandafter" container style
div.beforeandafter{ /* main container */
	background: white;
	border: 1px solid gray;
	display: block;
	width: 600px; /* width of largest image width */
	height: 400px; /* height of largest image height */
	overflow: hidden;
	position: relative; /* important */
}

Setting the outer container to a "relative" position facilitates what's to come next, which is to absolutely position the two inner DIVs and have them anchored relative to this outer DIV. This causes the two DIVs to stack on top of each other. The main magic happens inside the style of these children DIVs:

"before" and "after" DIVs style
div.before, div.after{ /* before and after DIVs within main container */
	width: 100%;
	height: 100%;
	top: 0;
	left: 0;
	position: absolute;
	overflow: hidden;
	transition: all 1s ease-in-out; /* CSS transition. */
	z-index: 100;
}

div.after{
	z-index: 1; /* z-index of after div should be smaller than before's */
}

div.beforeandafter:hover div.before{ /* onmouseover main container */
	width: 0; /* change "before" div width to 0 to hide it */
}

We position both DIVs to "absolute" to fill the entire area of the outer container, with the "before" DIV showing up on top by manipulating the two DIVs' z-index values. Furthermore, we've set the DIVs to "overflow: hidden"; this is a crucial part of the puzzle. By doing this, we can contract the width of the "before" DIV without clipping or hiding the image inside it to gradually reveal the "after" DIV and its image. The contraction of the "before" DIV is realized thanks to this selector and CSS:

div.beforeandafter:hover div.before{ /* onmouseover main container */
	width: 0; /* change "before" div width to 0 to hide it */
}

When the mouse rolls over the main container, we want to set the width of the "before" DIV to 0. This transition is smooth, as we've defined the "transition" property inside the children DIVs to transition any change in property values occurring inside them using a 1s duration and an "ease-in-out" timing function.

Going beyond the "width" property

A classic "before" and "after" effect has us transitioning merely the "width" property to collapse the before image and reveal the after image, but that doesn't mean we can't get a little creative. In the following examples, lets see the result of transitioning other properties in conjunction with "width", plus a different property altogether to see what kind of spin we can put on the default before/after effect:

Transitioning "width" and "opacity" in conjunction

div.beforeandafter:hover div.before{
	width: 0;
	opacity: 0;
}

Transitioning "width" and "height" in conjunction

div.beforeandafter:hover div.before{
	width: 0;
	height: 0;
}

Transitioning the "height" property

div.beforeandafter:hover div.before{
	height: 0;
}

Transitioning the "transform" property

div.beforeandafter:hover div.before{
	transform: rotate(360deg) translate3D(100%,100%,0)
}

Creating a flip card effect

div.beforeandafter{ /* main container */
	background: white;
	border: 1px solid gray;
	display: block;
	width: 234px; /* width of main container */
	height: 320px; /* height of main container */
	position: relative;
	perspective: 1000px; /* Greater the value, less pronounced the 3D effect */
}

div.before, div.after{ /* before and after DIVs within main container */
	height: 100%;
	position: absolute;
	left: 0;
	top: 0;
	width: 100%;
	z-index: 100;
	transform-style: preserve-3d; /* position both children DIVs in 3D space */
	transition: all 1s ease-in-out; /* CSS transition. */
}

div.after{
	transform: rotateY(-180deg); /* rotate "after" DIV by -180deg to start */
	z-index: 1; /* z-index of after div should be smaller than before's */
}

div.before{
	backface-visibility: hidden; /* hide backface of "before" DIV */
}

div.beforeandafter:hover div.before{
	transform: rotateY(180deg)
}

div.beforeandafter:hover div.after{
	transform: rotateY(0)
}

So as you can see, just by adjusting the CSS property that gets modified when the mouse rolls over the before/after container, we can create lots of variations on the original effect. The last example goes a step beyond to delve into 3D transformations.

Another area we can extend the "before and after" effect is to give the user the ability to load different set of images inside the same container, so multiple sets of images can be conveniently compared. Lets see how to do that on the next page.

A CSS Before and After image effect gallery