From our sponsor: Ready to show your plugin skills? Enter the Penpot Plugins Contest (Nov 15-Dec 15) to win cash prizes!
Today we want to share an experimental 3D layout with you. It’s inspired by the famous Flipboard app where a seamlessly “normal” page flips like a page in a book when swiped. We’ve tried to re-create that effect using CSS 3D transforms and JavaScript, making a layout that is “flippable” and responsive. While the swiping makes sense for touch devices, dragging will do for normal browsers.
For the demo, we’ve made a little booklet with some placeholder text and images from NASA HQ. The images are licensed under the Creative Commons Attribution-NonCommercial 2.0 Generic License. The placeholder text is by http://hipsteripsum.me/.
Please notice that this is very experimental and just a proof-of-concept. It was tested in the latest versions of Safari, Chrome and Safari Mobile. The behavior is unfortunately not as nice as expected in Firefox.
Tiny break: 📬 Want to stay up to date with frontend and trends in web design? Subscribe and get our Collective newsletter twice a tweek.
There are probably still many undiscovered bugs and although Safari and Chrome support all the properties used, we had to apply a couple of hacks to overcome some unexpected behavior. Let us know about your experience with it and how it performs.
Some of the jQuery plugins we are using for this:
- History.js for keeping track of the current state/pages
- TouchSwipe for dragging and swiping the pages
- Modernizr for checking browser support of the CSS properties
The HTML is build up of a main wrapper with the class container and the ID flip. Inside, we’ll have all the pages, the first one being the cover and the last one being the back of the booklet. The other pages will contain some title element and boxes. These boxes will each need an additional “height” and “width” class which will give the element percentage-based dimensions. For example, w-50 is a class that will give the element a width of 50%. Depending on how a page should be laid out, we would add a fitting set of items:
<div id="flip" class="container"> <div class="f-page f-cover"> <!-- ... --> </div> <div class="f-page"> <div class="f-title"> <!-- ... --> </div> <div class="box w-50 h-100"> <div class="img-cont img-1"></div> <h3>Headline <span>Published May 7, 2012</span></h3> <p>Some text</p> </div> <div class="box w-50 h-100"> <!-- ... --> </div> </div> <div class="f-page"> <!-- ... --> </div> <!-- ... --> <div class="f-page f-cover-back"> <!-- ... --> </div> </div>
We are applying some “tricks” for making everything work responsively. The images are background-images and we set the background size of that element to “cover” while leaving the width and height fluid, in percentages. That’s of course not how it should be done. But it’s just for demonstration purpose. The teaser text is already loaded, and just “cut off” because the box is set to overflow “hidden”. To make it look smoother, we’ve just added a pseudo-element with a white to transparent gradient which covers the last bit of the box.
A great help for creating responsive layouts like these is this:
* { box-sizing: border-box }
which finally got the attention it deserves thanks to this article by Paul Irish. When laying out elements using percentages it really comes in handy to use the border-box value since we can for example, define paddings in pixels and not break our 50% width box.
We will use jQuery Templates for creating the book structure:
<script id="pageTmpl" type="text/x-jquery-tmpl"> <div class="${theClass}" style="${theStyle}"> <div class="front"> <div class="outer"> <div class="content" style="${theContentStyleFront}"> <div class="inner">{{html theContentFront}}</div> </div> </div> </div> <div class="back"> <div class="outer"> <div class="content" style="${theContentStyleBack}"> <div class="inner">{{html theContentBack}}</div> </div> </div> </div> </div> </script>
The trick is to create a left side and a right side of a page, hiding half of each side to make it appear as one.
Before we call our experimental plugin, we need to check browser support first:
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script> <script type="text/javascript"> var $container = $( '#flip' ), $pages = $container.children().hide(); Modernizr.load({ test: Modernizr.csstransforms3d && Modernizr.csstransitions, yep : ['js/jquery.tmpl.min.js','js/jquery.history.js','js/core.string.js','js/jquery.touchSwipe-1.2.5.js','js/jquery.flips.js'], nope: 'css/fallback.css', callback : function( url, result, key ) { if( url === 'css/fallback.css' ) { $pages.show(); } else if( url === 'js/jquery.flips.js' ) { $( '#flip' ).flips(); } } }); </script>
If there is browser support for CSS 3D transforms and transitions we’ll load all the other necessary scripts and call our flips plugin.
Please note again that it’s only experimental, but nonetheless, I hope you find it interesting.
Doesnt work in chrome for me…
Amazin Work!
Really impressing … now there is a fantastic way to screen pdfs or other presentation files to the web.
Doesn’t work. 🙁
Chrome & FireFox.
Linux OS.
this is awesome!! perfectly executed! 🙂
why the flipboard tutorial download source isn’t working when i open in firefox, i have firefox 12..
but when in demo tutorial it’s working, although i open in the same browser ???
The same for me, the “on line” version works well on Firefox, but the downloaded source didnt do.
For the rest a GREAT experiment and very usable!
This demo just made me drop by stealth-eye-scope. WOW. Great work!.. contact me. I have a project for you.
smart execution with the responsive design!
Oh, Greate layout. I love it 😡
here’s the thing guys, chrome fails 3d transform test on Windows xp no matter, what version it is, observed similar behavior for jquery mobile transitions aswell.
This looks very nice (on Mac OS 10.6, chrome)!! curious how this works in iOS.
couple suggestions/feature requests: 1) key support (up/down/left/right) for flipping pages and shifting categories/feeds. Also maybe play with the mouse wheel clicks for left/right/scroll-up/down. This may make it more appealing to heavy keyboard and mouse users. 2) escape key as a back button.
Incredibly work!!
Thank you for sharing Pedro 🙂
WOW!
do the jquery flip do vertical flipping? Like the flipboard mobile app.
Wow amazing source for create a great web magazine .
This work fine with android ?
Fabulous work but I’ve spotted a slight flaw. When rotating between portrait and landscape on the iPad, it only resizes and adjusts every other rotation. Otherwise, absolutely smashing.
Very impressive plugin!
Hi,
I love this solution a lot. Now, I’ve been trying something else with the source, namely if canvas would be usable in this context.
It seems to work, at least, I can paste the code into the box-div and it loads up and also displays at the correct size in the modal box. There’s a few problems with this, however.
Before I go any farther: I use the software Hype 1.5 for Mac to generate canvasses with animations.
1st problem: The canvas loads in the box and you can see only part of it because it’s too big for the box (1024×768)
1st problem possible solution: Display a placeholder instead of the canvas in the non-modal view. Possibly an image or an image with some text. Then when the modal is loaded, show the canvas instead of the placeholder text. It should load only when the modal is used, however, since the canvas animations usually start on load.
2nd problem: I inserted the canvas code in box that spans both page 1 and 2 after the cover. When you flip the cover, the canvas seems to flicker through said cover, possibly any page that’s before it. When you flip the page where the canvas is at to the the next page, the left side of that page seems to become mirrored and has part of the canvas showing through.
2nd problem possible solution: Don’t make the canvas load until it’s needed. Just like solution 1, really.
I’m not too familiar with the code yet, but this should be easily fixable. Of course, I’ll try and do it myself, but if you want to have a shot at this be my guest. Please share your solution with us if you find one. I’ll try to do the same.
Anyway, keep these gorgeous solutions coming!
Outstanding! How would one go about making it advance to specific page if one was linking to a specific page?
Great work!
nm – I see – was hoping for in page animation but still outstanding.
is there an answere about the question above? “button to specific page if one was linking to a specific page”
thx
This layout is amazing. One thing i’m having issues with is how the images work. when i replace the stock fotos you added, when the box expands the image is not showing full size. It cuts off fine and looks nice before clicking on an article, but when clicked, its still cut off.
how to fix this resizing issue ?
should i add another img class for the box after expansion ?
any thoughts would be great..
Thanks in advance so much.
-uxepi
I use Firefox to view, it’s OK. But chrome can’t view as Firefox :-s
Great Job! And thanks for sharing this.
Amazing.. I love how flip board do their animation and same with this experiment.
This is great, Pedro. I was looking to do something similar, and stumbled upon this. This is why I love Codrops. I have a question though. Would it be possible to swipe the page without having to have the animation? Meaning, when you swipe to the left or right, part of the content shows up, but without the flip book animation. Sort of how we swipe from one desktop to the other on OS X Lion. Is that possible? And how would I go about achieving this?
Thanks and sorry if this question is a pain. Regards,
Patrick
Just have to say wow you got some skills Pedro
Hi Pedro,
I found a little problem in “jquery.flip.js” on the “_saveState” function. When running the code locally (my URL is “file://something/like/that.html”) I get a javascript exception that stop the script execution (don’t run the function “_onEndFlip” completely). This way, the variable “this.isAnimating” stay true and the fliping no longer works. I solved this problem using a try…catch statement:
try {
if( this.History.getState().url.queryStringToJSON().page !== page ) {
this.History.pushState( null, null, ‘?page=’ + page );
}
}
catch (err)
{
// nothing
}
I found another “problem” in this implementation when using on iPad (perhaps be a JQuery problem): when I click some “div.box” to open an article, nothing happens. I can only open an article if I click and hold for a hundred miliseconds (I can’t just “tap”). Debugging the code I notice that the JQuery click event is raised only in the second case. Anyone know how I can fix this?
I tried to change the index.html into a JSP file and everything jumbles up.
Is there something to setup before it can become a server page?
on firefox, the effect is too slowly
Hi, I love your lib. But I have a problem with it.
– How I can go to any page, ex: goto(page1), goto(page2),…
– And I can get instance of flip object?
Please help to clear my problem.
Hi. Anyone thought of making this into a wordpress theme?
Hi Pedro. Very good code sample, but I’m having a little problem.
I try to add pages dynamically. Everything looks OK, the generated code it’s exactly the same as the sampled code you give, but everything stops. I can’t swipe, turn pages, etc, is there anything I need to do after creating the new pages?
Thanks in advanced.
Best Regards,
bmsm
Awesome!! hope other browsers will support CSS 3D transforms and transitions!
Has anyone solved the image problem yet? I added in this missing piece of css:
.box-expanded.box-img-right .img-cont, .box-img-right .img-cont{ float: right; width: 40%; height: 100%; margin-left: 2%; }
But I am still have major issues with sizing and placement in the .box-expanded view, as well as with the borders, which seem to have a mind of their own. Any help with this would be much appreciated!
Awesome! support for mobile ?
Wow, this is amazing. Love it 😀 Handy for a school newpaper website or a cool article website 😀
Great work! Amazing effect!!
How do I implement the template and flip dynamically generated pages?
Is there a way to access the this._layout() method?
Thanks in advance!
Subhrajit
Love this one, good job!
Small question, lets say I have a hyperlink added called page 4. When clicking it, I would like to go to page 4 with the pageflip animation of course. How to do this?
I use android4.0.3 native browser and android chrome,,But the behavior is unfortunately not as nice as expected.
Native Browser : Click on the specific content of the focus is not accurate?Zoom in of the contents or Expansion, the effects are not smooth??
Flip effects are not smooth?
android chrome? Flip effects are not smooth?Content can not expand?
How can I solve this problem?Whether the android system or browser??
Look forward to your reply??
can someone tell me how to allow controls inside page divs to recieve mouse events, i.e click event?
this Does work on Ubuntu Google Chrome please check it
very nice tutorial, thanks for the share.
It’s not working for android 2.1, 2.2.
Exceptional. A shame it’s just an experiment and not something going to be completed as I’d gladly pay for this and support.
Wow it is soooo great effect thanks a lot..
Can this expand to allow us to process/parse some Rss Feeds ?
Would be awesome.
This is great, I hope you move this from experiment, this is awesome and much needed. Thanks
great tutorial and work amazing 🙂 thank you
Hello, i’d like to know how to flip the pages when a certain div element (added by me) is clicked
Thanks
Someone know what happens in iOS 6? The Articles doesn’t open.
Popups don’t work in iOS 6. :\