Christoph ZillgensBack to Home

I‘m an Interface Designer and Web Developer from Germany. Here are some example of my work at my one-man company

CSS3 3D bookshelf

When I read Tim van Damme’s great article on »24 ways« about CSS animations last year, I wasn’t only impressed by what he came up with, but also immediately felt that I had to play with stuff like this on my own.

The time was there when I redesigned my blog and I was thinking about a fun way to display my book section. I eventually found a way to pull the books out off the shelf by pure CSS magic.

In this post I gonna show how I did it.

The HTML

Well, as always it is important to have a clean and semantic HTML code:

<div id="shelf">
<ul>
	<li class="book1">
	<a href="#">
		<h2 class="spine">Title of book 1</h2>
		<p class="cover">
		<img src="cover1.jpg"  />
		</p>
	</a>
	</li>
	<li class="book2">
	<a href="#">
		<h2 class="spine">Title of book 2</h2>
		<p class="cover">
		<img src="cover2.jpg" />
		</p>
	</a>
	</li>
</ul>
</div>

Here we have simple list of book titles and their covers. I added more class names than I needed. This helped me to better understand my CSS later on. As you may have seen, I wrapped the »a« element around some block elements which is possible in HTML5.

The CSS magic

There is nothing special about the bookshelf styling itself, so we immediately jump to the interesting part. To be able to add CSS rules that only apply to browsers with support of 3D transforms we start with a media query:

@media (-webkit-transform-3d) {	
	…
	special CSS adjustments go here
	…
}

To understand what media queries do and what they are good for, read this great article on A List Apart.

Next we add a perspective to our »li« element and also define a transition:

li {-webkit-perspective: 5000; -webkit-transition: all 0.5s linear;}

For the »a« element we add this:

a {-webkit-transform-style: preserve-3d; -webkit-transform-origin: 42px;}

You remember the HTML? We wrapped the »a« element around the cover and the spine of the book. By defining »preserve-3d« we keep the 3D effect for the child elements of »a« instead of flatten them. Look a this example to see how it works.

Next, we have to build a real book. Well, a book is approximately a cuboid and the cover and the spine are two faces of this cuboid. So to put them in the correct position we have to move the spine on the z axis (towards the viewer) and to rotate the cover around the y axis:

.spine {-webkit-transform: translateZ(38px);}
.cover {-webkit-transform: rotateY(90deg) translateZ(-19px);}

Now the books are on the shelf and, of course, you can’t see the covers anymore.
To get some action we have to define »:hover« states, now.

We have to do two things: First, pull the book out of the shelf and second, turn the book to see the cover.

Trigger the animation

To make the first step happen, we just scale the whole book on »li:hover«:

li:hover {-webkit-transform:scale(1.3); z-index:1;}

Together with the transition defined for »li« before, we get the illusion of pulling the book towards the viewer.

We can use the child elements of »li« for another animation, namely the turning of the cover. Because this step should start when the book is out of the shelf, we add a delay to the transition:

li:hover a {-webkit-transform: rotateY(-90deg); -webkit-transition-delay:.5s;}

So the turning starts after the book was scaled and it looks like one continuous animation.

Bringing it all together

Here is the whole (simplified) CSS I used within the media query:

@media (-webkit-transform-3d) {
li {-webkit-perspective: 5000; -webkit-transition: all 0.5s linear;}
a {-webkit-transform-style: preserve-3d; -webkit-transform-origin: 42px;}
.spine {-webkit-transform: translateZ(38px);}
.cover {-webkit-transform: rotateY(90deg) translateZ(-19px);}
li:hover {-webkit-transform:scale(1.3); z-index:1;}
li:hover a {-webkit-transform: rotateY(-90deg); -webkit-transition-delay:.5s;}
}

We’re done. The final bookshelf CSS contains some more properties that are neccessary to make it work, but it would’ve been to complicated to explain them all. Watch the book page for the final result.

I hope it wasn’t too hard to understand what happens. If you are interested in things like this you should read the 3D transforms article on the Webkit blog.

Conclusion

First I have to say that I’m impressed by what you can achieve with only a few lines of CSS. Building it with Javascript or Flash would’ve been more complicated, at least for me. Also, this degrades well for less capable browsers, the users just see the covers immediately without animation, that’s all, and it is very accessible for anyone else. Building it on pure HTML makes it also possible to integrate the bookshelf into a CMS, which I did with Textpattern.

On the other hand there are also some downsides, of course. Currently the animation only works in Safari/Webkit on a Mac, even Chrome is not able to handle 3D transforms as I’m writing this post. Sometimes, it can be hard to read the spines whereas covers are more recognisable and easier to remember.

There might be some room for improvements but in the end I think it’s ok to experiment with it. We just scratched the surface of CSS3 and we’re up for some exciting times.

What do you think of the new CSS3 possibilities like animation, transform and transition?

8 comments

  1. Arno wrote 1555 days ago · #

    cool idea! but is it valid to have block elements like h2 or p nested inside inline-elements such as an anchor tag without having them be at least inline-blocks? just thinking. otherwise as I said, great idea.

  2. Christoph Zillgens wrote 1554 days ago · #

    Yes, it is valid and that alone is a reason to use HTML5. Look at the last paragraph in the spec.

  3. Hal wrote 1485 days ago · #

    I was happy to discover that your bookshelf animations work wonderfully on an Apple iPad. Cool!

  4. Garth Jantzen wrote 1446 days ago · #

    Nice work. Might want to consider changing your transforms to translate3d() or rotate3d() to push it on to the GPU. Anything in animation keyframes are automatically hardware accelerated, but with transitions, you need to add ‘3d’. Could make things run smoother.

  5. William Roe wrote 1248 days ago · #

    The animations have stopped working, seems to be due to stylesheets being moved. Both article37.css and stylesheet.css are not found.
    Looks like good work though.

  6. Endy wrote 1038 days ago · #

    wow what a great bookshelf,,,can i use it in my project ..?

    i want to make blog snapshot, but i’ll make looks like bookshelf..

  7. Prodyot wrote 968 days ago · #

    Great bookshelf.
    What a creation!
    Amazing.
    I tried it out in FF, Chrome and Safari.
    FF and Chrome could not deliver the 3D effects.
    But, Safari did a great job.
    Thanks for sharing.

  8. Simon wrote 872 days ago · #

    So, this post was a time saver in Language of &quot;Performance&quot; ! Hermila Ludemann dd1

Commenting is closed for this article.