CSS3 Page Flips

Works with Safari, iPhone, iPad.

In previous examples of page navigation we used various types of sliding effects to indicate to the use the transition from one section of a Web app to another. Now we’re going to look at how to indicate section transitions with various types of page flips. In order for these types of flips to work properly, we will need to enclose the items being rotated in a parent element that has the CSS3 property for transform style with a value of preserve-3d. We also need to define the perspective value. The higher the value, the further back from the element the viewer will be, reducing the perspective distortion. Similarly, the smaller the perspective value, the more pronounced the 3D effect will be. For something a little less pronounced I use a value of 1000, and for more pronounced: 500.

First we’re going to look at implementing a typical “card flip” effect. We’re going to implement this with the same basic layout that I created in earlier posts with backward and forwards navigation with a slide effect, except that the links will lead to pages with the various flips and rotations. So, the target of the menu items will contain a parent element, a div tag, which we’ll give a class of “card.” This will have the perspective values that will determine how the rotation looks with perspective distortion. Here’s the markup for the first section. The other section have the same markup, but a different identifier to allow for unique transforms on each section. One thing to bear in mind when implenting these types of transforms, the background of the body tag will show as the elements transition. So, you should make transforms elements’ backgrounds visually different from the background of your body tag so that you can see the elements as they are rotated easier.

<article id="Flip">
	<section class="card">
		<div class="face front">
			 <header>
				 <span class="button back"><span></span>Back</span>
				 <h1>Flip Page Over</h1>
				 <span  id="flipOverButton" class="button">Flip Over</span>
			 </header>
			 <div class="paddingWrapper">
				 <h2>This is the front</h2>
				 <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
		 </div>
		</div>
		<div class="face back">
			<header>
				<h1>Flip Page Over</h1>
				<span  id="flipBackButton" class="button">Flip Back</span>
			</header>
			<div class="paddingWrapper">
				<h2>This is the back</h2>
				<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
			</div>
		</div>
	</section>
</article>

Here’s the CSS we need to get the rotation flip to work:

#Flip {
	-webkit-perspective: 1000;
	position: absolute;
}
article .card {
	min-height: 100%;
	width: 100%;
	position: absolute;
}
.face {
	position: absolute;
	width: 100%;
	height: 100%;
	text-align: center;
	-webkit-backface-visibility: hidden;
	-webkit-transform-style: preserve-3d;
	-webkit-transition: all .5s ease-in-out;
}
#Flip .face.front {
	-webkit-transform: rotateY(0deg);
	background-color: #fffccf;
}
#Flip .face.back {
	-webkit-transform: rotateY(180deg);
	-webkit-box-sizing: border-box;
	background-color: rgba(0,0,0,0.125);
}
#Flip .face.front.flip  {
	-webkit-transform: rotateY(-180deg);	
}
#Flip .face.back.flip {
	-webkit-transform: rotateY(0deg);	
}

We define the perspective property -webkit-perspective: 1000 on the article tag with an id of #Flip. Then we set the initial rotation status of the two divs. For the frontmost div we give it a rotation of 0 degrees, and for the back one, a rotation of 180. We also give the div with the “face” class a CSS3 property to hide its rear side so that it doesn’t show when we rotate it: -webkit-backface-visibility: hidden;. Now, to initiate the flip effect all we have to do is use a little JavaScript to add and remove the “flip” class to the two elements.

Now let’s look at how to implement another flip effect that resembles a left page turn. This is basically the same as the card flip described above, except that we’re going to define the start position of the transform. By default the start position is at the center of the element’s y axis. We’re going to use -webkit-transform-origin: 0% 0%; If we used a value of -webkit-transform-origin: 100% 0%; the result would resemble doors swinging open and closed. Here’s the complete list of styles for the left page turn effect. Notice that we’ve decreased the perspective on the “card” class to 500:

#TurnLeft .card {
	height: 100%;
	-webkit-perspective: 500;
}
#TurnLeft {
	height: 100%;
	background: #cbd2d8;background-image: -webkit-gradient(linear, left top, right top, from(#c5ccd4), color-stop(0.75, #c5ccd4), color-stop(0.75, transparent), to(transparent)); 
	-webkit-background-size: 6px 100%;
}
#TurnLeft .face {
	position: absolute;
	width: 100%;
	height: 100%;
	-webkit-backface-visibility: hidden;
	-webkit-transform-style: preserve-3d;
	-webkit-transition: all .5s ease-in;
	-webkit-box-sizing: border-box
	text-align: center;
}
#TurnLeft .face.front {
	background-color: #fffccf;
	background-image: -webkit-gradient(linear, left top, right top, from(rgba(197, 204, 212, 0.5)), color-stop(0.75, rgba(197, 204, 212, 0.5)), color-stop(0.75, transparent), to(transparent)); 
	-webkit-background-size: 5px 100%;
	-moz-background-size: 7px 100%;
	-webkit-transform-origin: 0% 0%;
	-webkit-transform: rotateY(0deg);
}
#TurnLeft .face.back {
	-webkit-transform: rotateY(180deg);
	-webkit-box-sizing: border-box;
	background-color: rgba(122,137,212,0.25);
	-webkit-transform-origin: 0% 0%;
}
#TurnLeft .face.front.turnLeft  {
	-webkit-transform: rotateY(-180deg);	
}
#TurnLeft .face.back.turnLeft {
	-webkit-transform: rotateY(0deg);	
}

So, once again we can trigger the turn page left effect by adding and removing the “turnLeft” class to the necessary elements.

Lastly, we’ll look at how to do a swing back and down effect. Notice that we’re not rotating on the y-axis but on the x-axis. This causes the elements to rotate on their x-axis:


#SwingBack .card {
	min-height: 100%;
	-webkit-perspective: 500;
}
#SwingBack {
	height: 100%;
	background: #cbd2d8;background-image: -webkit-gradient(linear, left top, right top, from(#c5ccd4), color-stop(0.75, #c5ccd4), color-stop(0.75, transparent), to(transparent)); 
	-webkit-background-size: 6px 100%;
}
#SwingBack .face {
	position: absolute;
	width: 100%;
	height: 100%;
	-webkit-backface-visibility: hidden;
	text-align: center;
	-webkit-transform-style: preserve-3d;
	-webkit-transition: all .5s ease-in-out;
	-webkit-box-sizing: border-box
}
#SwingBack .face.front {
	background-color: #fffccf;
	background-image: -webkit-gradient(linear, left top, right top, from(rgba(197, 204, 212, 0.5)), color-stop(0.75, rgba(197, 204, 212, 0.5)), color-stop(0.75, transparent), to(transparent)); 
	-webkit-background-size: 5px 100%;
	-moz-background-size: 7px 100%;
	-webkit-transform-origin: 0% 0%;
	-webkit-transform: rotateX(0deg);
}

#SwingBack .face.back {
	background-color: #fffccf;
	background-image: -webkit-gradient(linear, left top, right top, from(rgba(197, 204, 212, 0.5)), color-stop(0.75, rgba(197, 204, 212, 0.5)), color-stop(0.75, transparent), to(transparent)); 
	-webkit-background-size: 5px 100%;
	-moz-background-size: 7px 100%;
	-webkit-transform: rotateX(180deg);
	-webkit-box-sizing: border-box;
	-webkit-transform-origin: 0% 100%;
}
#SwingBack .face.front.swingBack  {
	-webkit-transform: rotateX(-180deg);	
}
#SwingBack .face.back.swingBack {
	-webkit-transform: rotateX(0deg);	
}

And here’s a working example online, or you can download the source. Enjoy.

About Robert Biggs
Front end Web developer skilled at creating interactive, dynamic interfaces using HTML5, CSS3, JavaScript, SVG. Passionate about developing awesome user experiences in the mobile space.

Comments are closed.