Menu Search
Jump to the content X X
Smashing Conf New York

We use ad-blockers as well, you know. We gotta keep those servers running though. Did you know that we publish useful books and run friendly conferences — crafted for pros like yourself? E.g. upcoming SmashingConf New York, dedicated to smart front-end techniques and design patterns.

Beercamp: An Experiment With CSS 3D


I recently had the pleasure of organizing this year’s Beercamp website. If you’re unfamiliar, Beercamp is a party for designers and developers. It’s also a playground for front-end experimentation. Each year we abandon browser support and throw a “Pshaw” in the face of semantics so that we can play with some emerging features of modern browsers.

This year’s experiment: a 3D pop-up book á la Dr. Seuss. If you’ve not seen it, hop on over and take a look. The website was a test to see how far SVG and CSS 3D transforms could be pushed. I learned a lot in the process and wanted to share some of the techniques that I found helpful when working in 3D space.

“Beercamp 2012: A Tale of International Mischief”

Before we jump in, please note that explaining everything about the website without boring you to death would be damn near impossible. For your sake and mine, I’ll provide just brief takeaways. As you skim through the code snippets, be aware that jQuery is being used and that a lot of code has been removed for simplicity (including browser prefixes).

Finally, please remember that this is an experiment! It will not work in all browsers. It does not degrade gracefully, and the markup is less than poetic. Put your convictions on hold for a moment and let’s have some fun.

Takeaway #1: Exploring 3D Space Is Fun Link

Before I started building the Beercamp website, I did some “research” into what makes pop-up books so much fun. As I flipped through the paper-crafted version of Dr. Seuss’ Oh, the Places You’ll Go, I found myself inspecting each page from multiple angles. Seeing how things looked from different perspectives was fun, and interacting with the environment was engaging.

The inspiration for Beercamp: Dr. Seuss’ “Oh, the Places You’ll Go.”

I wanted to create that same engagement in my digital version with intuitive and unobtrusive controls. Thus, the scene rotates based on the mouse’s coordinates, allowing the user to move the book around without much effort. Achieving this was pretty easy:

1. Set up a listener.

This is for the mousemove event.


2. Calculate the rotation.

I wanted the book to rotate between -15 and 15 degrees, based on where the mouse is located along the x axis. This can be calculated using the following:

rotationY = -15 + (30 * e.pageX / $body.width());

3. Apply the rotation.

$scene.css('transform': 'rotateY(' + rotationY + 'deg)');

Pretty simple, right? The only problem is that our friends on iPhones and iPads don’t have mouse coordinates. They do, however, have a gyroscope. Rotating a phone is very similar to rotating a book, so adjusting the scene based on the device’s orientation made for an intuitive and delightful interaction. Setting this up was similar but slightly more involved.

1. Set up a listener.

window.addEventListener('deviceorientation', rotateScene, false);

2. Determine the orientation.

Before we can calculate the rotation, we need to know whether the device is in landscape or portrait mode. This can be determined by evaluating window.orientation:

  • Landscape
    Math.abs(window.orientation) == 90
  • Portrait
    window.orientation == 0

Determine the device’s orientation by evaluating window.orientation.

3. Calculate the rotation.

Now that we have the orientation, we can pull in the appropriate values from the gyroscope. If the device is in landscape mode, we’ll tap the beta property. Otherwise, we’ll use gamma.

var theta = (Math.abs(window.orientation) == 90) ? e.beta : e.gamma;
rotationY = 0 + (15 * (theta / -45));

The deviceorientation event enables us to pull alpha, beta and gamma rotation values. Note that these values are relative to the current orientation of the device. The image above shows the axes of a phone held perpendicular to the ground in portrait mode.

4. Apply the rotation.

$scene.css('transform': 'rotateY(' + rotationY + 'deg)');

Takeaway #2: Depth-Sorting Is Notoriously Buggy Link

A number of browsers support 3D transforms, but few do so elegantly. Apart from general efficiency issues, the biggest hindrance is improper depth-sorting.

Depth-sorting is required when two planes intersect in three-dimensional space. The rendering engine must determine which plane (or, more specifically, which areas of the plane) should be rendered and which should be clipped.

Depth-sorting varies across browsers.

Unfortunately, each browser implements depth-sorting differently and, therefore, has its own issues. The best we can do to combat the glitchy pop-through of underlying elements is to keep planes away from each other.

The Beercamp website involves numerous plane intersections. Initially, I had all of the pages rotating around the same point in 3D space (0, 0, 0). This meant that just about every plane in the book was fighting to be on top. To counter this, the pages needed to be positioned as if they were next to each other along the spine of an actual book. I did this by rotating the pages around an arc, with the open page at the pinnacle.

Rotating pages around an arc helps to prevent clipping.

function updateDrag(e) {
    // operate on each spread
   $('.spreads li').each(function(i) {
        // calculate the angle increment
        var ANGLE_PER_PAGE = 20;

        // determine which slot this page should be turned to
        var offsetIndex = per < 0 ? 5 + curPageIndex - i : 5 + curPageIndex - i - 2;

        // calculate the angle on the arc this page should be turned to
        var offsetAngle = per < 0 ? offsetIndex - per - 1 : offsetIndex - per + 1;

        // calculate the x coordinate based on the offsetAngle
        var tarX = 5 * Math.cos(degToRad(offsetAngle * ANGLE_PER_PAGE + 10));

        // calculate the z coordinate based on the offsetAngle
        var tarZ = 5 * Math.sin(degToRad(offsetAngle * ANGLE_PER_PAGE + 10));

        // position the page
        $(this).css('transform', 'translateX(' + tarX.toFixed(3) + 'px) translateZ(' + tarZ.toFixed(3) + 'px)');

This technique helped to clear up most of the depth-sorting issues, but not all of them. Further optimization really relies on the browser vendors. Safari seems to have things worked out on both desktop and mobile. Chrome Stable struggles a bit, but the latest Canary works wonderfully. Firefox does a fine job but suffers from slow frame rates. It’s a tough battle to win right now.

Takeaway #3: Vector Space Is Tricky But Useful Link

Building the pop-ups was by far the most difficult aspect of the project, but also the most satisfying. Other pop-up books have been built on the Web, but I’m unaware of any that use realistic pop-up mechanics. This is with good reason — achieving it is deceptively complex.

The magic of programming pop-up mechanics lies in the calculation of vector space. A vector is essentially a line. Knowing the lengths and directions of lines enables us to perform operations on them. Of particular use when building pop-ups is the vector cross product, which is the line that runs perpendicular to two other lines in 3D space.

The cross product is important because it determines the upward rotation of each pop-up piece. I’ll spare you the headache of play-by-play calculations (you can view the math below if you’re really interested). Instead, let’s try a visual representation.

The vector cross product in action.

We start by determining two points where each pop-up piece touches the page within 3D space. Those points are used to define a vector for each pop-up piece (the red lines). Using those vectors, we can calculate their cross product (the blue line), which is essentially the line at which a physical pop-up folds in half. Rotating each piece up to the cross product then gives us perfectly aligned pop-ups!

This is not exactly easy math in my opinion, but it is extremely useful. If you’re interested in playing with vectors, I strongly recommend Sylvester61. It really simplifies vector math.

function setFold() {
    var points = [];

    // origin
    points[0] = [0, 0, 0];

    var adj = Math.sqrt(Math.pow(POPUP_WIDTH, 2) - Math.pow(POPUP_WIDTH * Math.sin(degToRad(-15)), 2));

    // left piece: bottom outside
    points[1] = [-adj * Math.cos(degToRad(-180 * fold)), adj * Math.sin(degToRad(-180 * fold)), POPUP_WIDTH * Math.sin(degToRad(-15))];

    // right piece: bottom outside
    points[2] = [adj * Math.cos(degToRad(-180 * 0)), POPUP_WIDTH * Math.sin(degToRad(-180 * 0)), POPUP_WIDTH * Math.sin(degToRad(-15))];

    // left piece: top inside
    points[3] = [-POPUP_WIDTH * Math.cos(degToRad((-180 * fold) - 90)), POPUP_WIDTH * Math.sin(degToRad((-180 * fold) - 90)), 0];

    var len = Math.sqrt(Math.pow(points[1][0], 2) + Math.pow(points[1][1], 2) + Math.pow(points[1][2], 2));

    // normalize the vectors
    var normV1 = $V([points[1][0] / len, points[1][1] / len, points[1][2] / len]);
    var normV2 = $V([points[2][0] / len, points[2][1] / len, points[2][2] / len]);
    var normV3 = $V([points[3][0] / len, points[3][1] / len, points[3][2] / len]);

    // calculate the cross vector
    var cross = normV1.cross(normV2);

    // calculate the cross vector's angle from vector 3
    var crossAngle = -radToDeg(cross.angleFrom(normV3)) - 90;

    // transform the shape
    graphic.css('transform', 'translateY(' + depth + 'px) rotateZ(' + zRot + 'deg) rotateX(' + crossAngle + 'deg)');

Takeaway #4: SVG Is Totally Tubular Link

I know, I know: you’ve heard the case for SVG before. Well, you’re going to hear it again. SVG is an incredible technology that works really well in 3D space. All of the illustrations on the Beercamp website were done in Illustrator and exported to SVG. This provided numerous benefits.

Benefit 1: Size Link

Because the pop-up pieces required large areas of transparency, the file-size savings of SVG were enormous. PNG equivalents would have been 200 to 300% larger than the uncompressed SVGs. However, we can reduce file size even more by exporting illustrations as SVGZ.

SVGZ is a compressed version of SVG that is incredibly small. In fact, the SVGZ files for Beercamp are up to 900% smaller than their PNG equivalents! Implementing them, though, requires some server configuration. This can be done easily with an .htaccess file:

AddType image/svg+xml svg svgz
AddEncoding gzip svgz

Benefit 2: Flexibility Link

The flexibility of SVG is perhaps its most highlighted benefit. The graphics on the Beercamp website are scaled in 3D space to fill the browser window. There are also hotspots on each page that allow the user to zoom in for more details. Because everything is handled with SVG, the illustrations remain crisp and clean regardless of how they’re manipulated in 3D space.

SVG files are inherently responsive.

Benefit 3: Self-Contained Animation Link

All of the SVGs on the Beercamp website are implemented as background images. This helps to keep the markup clean and allows images to be reused in multiple locations, such as with the pop-up pieces. However, this means we lose DOM access to each of the nodes. So, what if we need some animation on the background SVGs?

SVG allows us to define animations within the file itself. All of the pop-up images in the final Beercamp website are static, but an earlier version featured animated beer bubbles. To increase performance in some of the less-capable browsers, these were taken out. However, the SVG animations ran very smoothly in WebKit.

SVG animation gets less hype than its CSS cousin, but it’s just as capable. Within an element, we can add an animate node to specify typical animation settings: properties, values, start time, duration, repeat count, etc. Below is an excerpt from one of the Beercamp bubbles.

<circle fill="#fff" opacity=".4" clip-path="url(#right-mug-clip)" cx="896" cy="381" r="5">
    <animate attributeType="XML" attributeName="cx" from="890" to="881" begin="7s" dur="5s" repeatCount="indefinite" />
    <animate attributeType="XML" attributeName="cy" from="381" to="100" begin="7s" dur="5s" repeatCount="indefinite" />

Takeaway #5: Experimentation Is Messy But Important Link

Now that the practical tidbits are out of the way, I’d like to say a word about experimentation.

It’s easy to get boxed in by the reality of developing websites that are responsive, cross-platform, cross-browser, gracefully degrading, semantically perfect, progressively enhanced, _______, _______ and _______ (space to fill in upcoming buzzwords). These techniques are useful on production websites to ensure reach and consistency, but they can also limit our creativity.

I’ll be the first to admit it: the Beercamp website is buggy. Browser support is limited, and usability could be improved. However, the website is an experiment. It’s meant to explore what’s possible, not satisfy what’s practical.

A dogma is emerging in our industry — and the buzzwords above are its doctrine. Experimentation enables us to think beyond that dogma. It’s a wonderful exercise that indulges our curiosity, polishes our talent and ultimately advances our industry. If you’re not experimenting in some capacity, you should be.

The State of CSS 3D Link

CSS 3D has yet to hit a tipping point. Browsers simply don’t support it well enough, but there is promise on the horizon. Mobile Safari, with its hardware acceleration, renders 3D transforms extremely fast and with very little depth-sorting issues. It’s only a matter of time until other manufacturers release stable implementations. It’ll be interesting to see how CSS 3D techniques hold up against other emerging technologies, such as WebGL.

Remember Flash? Me neither.

You’re Invited Link

By the way, Beercamp is being thrown by nclud2 at the Front-Trends Conference83 in Warsaw. If you’re headed to the conference, you should stop by and say hello!


Footnotes Link

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
SmashingConf New York

Hold on, Tiger! Thank you for reading the article. Did you know that we also publish printed books and run friendly conferences – crafted for pros like you? Like SmashingConf New York, on June 14–15, with smart design patterns and front-end techniques.

↑ Back to top Tweet itShare on Facebook

Tom Giannattasio happily makes things at nclud. He works as an Editor for Smashing Magazine and teaches at Boston University Center for Digital Imaging Arts. He loves to experiment and share his work on his personal site: attasi.

  1. 1

    who can see the alive site? I cannot see by my Chrome and Firefox.

  2. 2

    No need to get defensive. The OP is just stating the fact that this could have been done with old tech much better. That is know reason to say that they are not the target audience. Not every designer is a developer, that said the project looks great and will be really appreciated by anyone with an interest in how browser technology and code is evolving.
    Thanks for the great article and snippets of code explaining the project.

  3. 3

    Jens Grochtdreis

    April 17, 2012 5:21 am

    Well, I remember Flash. It is the right tool for such a task. As a Flash-page I would have no performance issue I do have with my newest Chrome. And the newest Opera could show me the content which is now not the case. Even on IE 8 and before I could reach the content. Now I only see two colors.

    It is interesting to see what can be accomplished with modern techniques. But that doesn’t necessarily mean the use of those techniques makes sense. In this case I would prefer a Flash page. It is far from fun to use this page.

  4. 4

    Godlike !

  5. 5

    Jelmer Borst

    April 17, 2012 5:43 am

    This is pure awesome! My dimensional calculus may in the end then still pay off :)

    Even though when flipping pages, some elements flicker a bit when they cross each other but no performance issues (Chrome 19). There is not a very big browser support (darn you, IE!) but one can dream and after a couple of years this might be the new buzz in design!

    Thanks for the article

  6. 6

    Mark Simpson

    April 17, 2012 5:45 am

    > Well, I remember Flash. It is the right tool for such a task.
    The point. You’ve missed it.

    > In this case I would prefer a Flash page.
    Web design 101: Always design for your target market.
    You are not the target market for this website. The type of people who they are targeting would absolutely love the Beercamp website.

  7. 7

    Donovan du Plessis

    April 17, 2012 6:03 am

    @Jens Grochtdreis

    Did you miss the paragraph: “Finally, please remember that this is an experiment! It will not work in all browsers. It does not degrade gracefully, and the markup is less than poetic. Put your convictions on hold for a moment and let’s have some fun.”

    Clearly you conveniently missed this? I suppose you just feel you just have to have your say, letting us know that the use of modern techniques doesn’t necessarily make sense? Pathetic.

    How about instead of advocating flash, work on your inability to comprehend the article for what it is trying to convey?

  8. 8

    Jens Grochtdreis

    April 17, 2012 6:19 am

    How do you know that I am not the target? Because I prefer to use the technique which is most useful? If the target market does only exist in game-loving teenies then I am really not the target market.

    But if you read the article correct there is no idea of a target market. The only idea was to test a technique for the techniques sake. The developer himself was the only target market.

  9. 9

    Good work, but i don’t like your last sentence.
    Doesn’t work on my updated Chrome, i7 with 12 gigs of ram (usable but lot of visual glitches and i can’t read aliased texts).
    So, yes, i remember Flash. And you should too.

  10. 10

    As a flash page you would not be working on all ipads and iphones.This is a test and you missed the point. Its to show it “can” be done. Now it needs to be perfected.
    If you actually had big clients, you would understand that they do not want just flash. The want an alternative for ipads as they want it to work “EVERYWHERE”, and they will pay big bucks for it. Having a flash version and an alternate version for ipads is the Only way for you to satisfy their needs. Therefore, this is extremely usefull. I hate people who think its either, or. The right answer is “BOTH”. And people who are thinking this way are making big bucks while the others are missing the boat.

  11. 11

    Completely agree. This is definitely impressive, but example of this kind (and better performing ones too) have been around for years. Why you would choose this over a technology that is browser independent and with better performance baffles me.

  12. 12

    Tom Giannattasio

    April 17, 2012 6:53 am

    Sometimes the medium is the message. The Beercamp site was an experiment built for a conference focused on frontend technologies. It was meant to highlight the recent advancements in CSS 3D and how well SVG can be integrated. I agree that Flash would run smoother, but that would go against the entire point of the site.

  13. 13

    Works great in the browser but i didn’t have the best experience on my iPhone.

  14. 14

    You are really missing the point…

    Most experiments will fail and sometimes all we can say is “cool!” and never use it. If you don’t experiment, you won’t grow… how do you think the web has evolved? By using blink tags instead of flash animations? Besides, the target audiences of Beer Camp were designers and developers whom don’t give a rat about cross browsers and have “REAL” fun with modern technologies.

  15. 15

    Impressive piece of work!
    I like the artwork and the animation. Thanks for sharing.

  16. 16

    Anthony Sessa

    April 17, 2012 8:50 am

    Super well done within the limitations of what browsers can do – which I think was that goal of the concept right!?

    Great write up as well.

  17. 17

    Hmmmmm… css3 everyday become stronger and stronger.. I can’t imagine 2 years from now, what css3 can do.. it will be wonderful absolutely…

  18. 18

    Love the site, love the effect and, most of all, love the illustrations which are outstanding.
    Well done and thanks for sharing.

  19. 19

    Tom Giannattasio

    April 17, 2012 1:18 pm

    Thanks, Bob! I’m glad you like it.

  20. 20

    Tom Giannattasio

    April 17, 2012 1:18 pm

    It absolutely was the goal! Thanks.

  21. 21

    Great article & great site! I remember looking at the beercamp2012 site a few weeks ago, and it was a little buggy/skittish – but it’s running really smoothly in chrome now. Have you been making tweaks over that time? Cause it looks great!

  22. 22

    Good Stuff, good read.

  23. 23

    Daniel Jimenez

    April 17, 2012 6:17 pm

    Interesting comment, I think I can see your point of view, and I tend to agree that as this is a front end technology focused event the medium is the message. However I also think that the medium can also be taken as online and the content itself is the demo/experiment. In this case the content is the message IMHO…

  24. 24

    Great read and a fantastic end result, I would love to do some experimentation like this.

  25. 25

    Very good example for developer. CSS3 and 3D will be future of web…:)

  26. 26

    This is great!
    Unf. it doesn’t work on iOS Safari (iTouch Retina), it keeps crashing as soon as I see the Book.

  27. 27

    Great to see creative experimentation like this, and i think the end result is awesome. This sort of design makes me think that there is so much potential for CSS in the future. Thanks for the post.

  28. 28

    Nice article.CS3 became much more efficient for Photoshop user.

  29. 29

    Related to the Front-Trends conference is a game about the speakers, Front-Face:
    Could be mentioned in related links.

  30. 30

    Looks cool in Chrome but doesn’t work on an iPhone 4 at least not for me.

  31. 31

    Mark Simpson

    April 18, 2012 3:03 am

    Because this is an event for people who are experimenting with new frontend technologies.

    This is not an event for web design, or the best way to animate elements on a page, this is an event where people go to learn about pushing the boundaries of frontend web technologies.

    Using flash for this website would be like using to run the website.

  32. 32

    Tom Giannattasio

    April 18, 2012 3:20 am

    My colleague John Shulz (@JFSIII) has been hard at work optimizing the mess I’ve made. He’s made some incredible improvements!

    The Chrome Dev team has also been optimizing some of the browser’s 3D capabilities around the Beercamp site. Chrome Canary is running things wonderfully now!

  33. 33

    Remember Ajax? DHTML? Me neither. The only good thing in that article is the 3D and SVG part, but you know we Flash devs have done that 10 years ago already. Let’s discuss on all that once it works on all browsers at the same speed. Something that Flash also do for 10 years.

  34. 34

    Fun experiment or not, when that page is the first search engine result that comes up for “Beercamp 2012” and there isn’t even an aplogetic “Sorry this wont work in your current browser, please visit this site in X.” and/Or the content of the site available in a different format for those browser this experiment wont run on, thats bad practice.

  35. 35

    And what if you want the site to be used on a mobile platform?

  36. 36

    Very cool Chris. Thanks for pushing the envelope and showing us what can be done with new capabilities. It’s experiments like this one that inspires and moves our industry forward.

  37. 37

    Brandon Cordell

    April 18, 2012 4:46 am

    It works just fine in Firefox and Chrome… try upgrading to a decent version and you won’t have a problem.

  38. 38

    Brandon Cordell

    April 18, 2012 4:52 am

    Flash did this 10 years ago… so I guess there is no point in innovating technology then. Don’t worry everybody, Flash will continue to provide our 3d needs for 10 more years! Who cares if it’s a slow resource hog on some systems, if they’re system can’t handle it, they must not be target audience! Hooray Flash, the answer to all our problems!

    Nothing like dogging on technology in it’s infancy. Putting it aside like it won’t ever be relevant. The standards are still being written and nothing is set in stone, not to mention browser support is slow but steady. It’s ok to accept the future of the web, even if that puts Flash developers in their own small, specific niche little corner of the world.

  39. 39

    Remember Flash? Me neither.

  40. 40

    Except that these horses have rockets on their backs…

    In all seriousness though I didn’t mean to come off so aggressively – I really did mean it when I said this was impressive. I also appreciate the fact that the goal here was to push forward new technology.

    That doesn’t change the fact though that if someone wanted to achieve something similar to this in a website for consumers then flash would be much more suitable. It would be interesting though to see how this performed on the iPhone/iPad.


↑ Back to top