Anders Tornblad

All about the code

Revisiting CssFlip

When I first started experimenting with modern Web APIs, 3D transforms was still an experimental feature. Browser support was limited and shaky, and required vendor prefixes. These days support is much better, but there are still a lot of quirks when it comes to browser implementation.

Back in 2011, I wrote a demo called CSS Page Flip, using a combination of CSS and some JavaScript to let a user flip through pages in a book. The transitions are declared in CSS and are triggered by JavaScript. Pages on the left have their transform-origin set to their right edge, which is aligned to the horizontal center of the screen, while pages on the right have their transform-origin set to their left edge. By applying backface-visibility: hidden, I can then rotate pages along the Y axis for a pretty simple effect.

#book { perspective: 2000px; transform-style: preserve-3d; } .page { width: 50%; height: 100%; position: absolute; top: 0px; left: 0px; margin-left: 50%; overflow: hidden; transform-style: flat; backface-visibility: hidden; transition: none; transform: none; } .page:first-child { margin-left: 0px; transform-origin: right center; } .page:last-child { transform-origin: left center; } .currentFold.forward > .page:last-child { transform: rotateY(0deg); } .nextFold.forward > .page:first-child { transform: rotateY(179.9deg); } .currentFold.backward > .page:first-child { transform: rotateY(0deg); } .nextFold.backward > .page:last-child { transform: rotateY(-179.9deg); } .folding .page { transition: all 1s ease-in-out; } .folding > .currentFold.forward > .page:last-child { transform: rotateY(-179.9deg); } .folding > .nextFold.forward > .page:first-child { transform: translateZ(1px) rotateY(0deg); } .folding > .currentFold.backward > .page:first-child { transform: rotateY(179.9deg); } .folding > .nextFold.backward > .page:last-child { transform: translateZ(1px) rotateY(0deg); }

It took a lot of fiddling to find good values for rotateY(). Almost every new version of Webkit broke my experiment, but I eventually settled on a combination of 0deg, -180deg and 180deg.

CSS Flip in EdgeEdge behaving badly A couple of years later, the major browsers started supporting 3D transforms, even without vendor prefixes. Unfortunately all of them have different ideas about how to transition from 180deg or -180deg to 0deg. Finally I thought of forcing the browsers to do what I want by having -179.9deg and 179.9deg. This works fine now, unless for (of course) IE and Edge. IE doesn't even support 3D transforms correctly without prefix, and for some reason Edge treats the transformation matrix differently than the other browsers, completely breaking part of the animation.

Apart from the page flipping, the demo also has an automatic page layout mechanism that reflows the chapters and the text blocks when needed. In the original demo, the contents of the book was actually a detailed description of how the demo was made, but unfortunately the original content was lost at some point. Now it is my personal story instead. Enjoy!

During the next week or two, I will make an effort to bring the solution forward into the 2016 state of mainstream browsers, including the following:

  • Fix scroll wheel flipping in Firefox
  • Handle chapter navigation using history.pushState()
  • Add some interactive stuff on some of the pages
  • Some effort of fixing the weird behavior in Microsoft Edge
  • Minimal effort of making it work in Microsoft IE

When that is done, I will open-source the whole thing on GitHub.

Add a comment