November 29, 2013

Create a 3D Book Animation with CSS

For his  new book, Photography for Designers, author Tom Kenny wanted to do something interesting with the image of the book itself on the website. His first thought was to perfectly render a physical book in Photoshop, right down to the very last detail but then he decided to do something interesting with CSS.

Read what Tom has done:

With the introduction of transforms in CSS, we can now replicate 3D objects. The 3D book I’ve created consists of two elements, the spine and the cover.

Step 1

<div class="book-container">

 <div class="book">
  <div class="book-cover">
   <img src="images/cover.jpg" />

  <div class="book-spine">
   <h1>The Book's Spine Text</h1>


Step 2

---------------------------------------------------------------------------------------------------------------------------------------------------- */
.book-container { width: 375px; margin: 0 auto; display: block;
 -webkit-perspective: 1200px;
 -moz-perspective: 1200px;
 perspective: 1200px;

.book { z-index: 5; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.25);
 -webkit-transition: 0.75s;
 -moz-transition: 0.75s;
 transition: 0.75s;
 -webkit-transform-style: preserve-3d;
 -moz-transform-style: preserve-3d;
 transform-style: preserve-3d;
 -webkit-transform-origin: 125px 0;
 -moz-transform-origin: 125px 0;
 transform-origin: 125px 0;
.book:after { content: ""; position: absolute; top: 0; bottom: 0; left: 3px; width: 7px; background: url(images/ridge.png) repeat-y; z-index: 20;
 -webkit-transform: translateZ(1px); /* Fix for flickering in Chrome  */
.book:hover {
 -webkit-transform: translateX(-10px) translateZ(35px) translateX(35px) rotateY(45deg);
 -moz-transform: translateX(-10px) translateZ(35px) translateX(35px) rotateY(45deg);
 transform: translateX(-10px) translateZ(35px) translateX(35px) rotateY(45deg);

Book cover and spine
---------------------------------------------------------------------------------------------------------------------------------------------------- */
.book-cover { position: relative; z-index: 10; }
.book-cover img { vertical-align: bottom; max-width: 100%; height: auto; }

.book-spine { position: absolute; color: #fff; position: absolute; bottom: 0; top: 0; width: 50px; z-index: 5; overflow: hidden; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.25); background: url(images/spine.jpg) -64px 0 no-repeat; background-size: auto 100%;
 -webkit-transform: rotateY(-90deg) translateX(-49px);
 -moz-transform: rotateY(-90deg) translateX(-49px);
 transform: rotateY(-90deg) translateX(-49px);
 -webkit-transform-origin: 0 0;
 -moz-transform-origin: 0 0;
 transform-origin: 0 0;
.book-spine h1 { display: block; width: 325px; text-align: left; color: #fff; position: absolute; top: 0; left: 39px; text-indent: 43px; text-transform: uppercase; font-family: "league_gothic_condensedRg", "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: 2em; opacity: 0.75; font-weight: normal;
 -webkit-font-smoothing: antialiased;
 -webkit-transform: rotateZ(90deg);
 -moz-transform: rotateZ(90deg);
 transform: rotateZ(90deg);
 -webkit-transform-origin: 0 0;
 -moz-transform-origin: 0 0;
 transform-origin: 0 0;
.book-spine:before { display: block; content: ""; width: 100%; height: 100%; background: rgba(0, 0, 0, 0.3); }

What we’re basically doing is rotating .book-spine, using CSS transforms, to the position it would be as if it were a real book and then, on hover, we’re rotating .book to reveal the spine and to show off the book in all its 3D glory. We’re doing this with the help of transitions too, of course.

The great thing is, if browsers don’t support transforms, they will only see a flat image of the cover. Initially I noticed the cover would be obscured by the spine in browsers without transform support as shown in the illustration below:

To fix this, all we have to do is give the cover a greater z-index than the spine. Now the spine will sit below the cover and be unseen if the browser doesn’t support transforms.

Chrome Glitch

During development, I had a weird flickering issue with the ridge (shadow image on the left of the cover) in Chrome when the book was hovered over and the transform and transitions were occurring. To fix that, I pulled the ridge (which is applied via an :after psuedo element) away from the cover by 1px by using translateZ(1px).

I can’t seem to replicate that issue now so it must have been happening on an older version of Chrome but I’ve left the fix in there for now.


You can see it in action in the demo here.

You can see download the CSS code here.


Post a Comment