Experimental Page Layout Inspired by Flipboard

An experimental page layout that let's you navigate pages by swiping or dragging as in a booklet, inspired by Flipboard.

Experimental Page Layout Inspired by Flipboard

View demo Download source

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.

FlipboardPageLayout01

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/.

FlipboardPageLayout02

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.

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.

FlipboardPageLayout03

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.

FlipboardPageLayout04

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.

View demo Download source

Previous:
Next:

Tagged with:

Related Articles

CSS Reference

Learn about all important CSS properties from the basics with our extensive and easy-to-read CSS Reference.

It doesn't matter if you are a beginner or intermediate, start learning CSS now.

Feedback 122

Comments are closed.
  1. 4

    Wow amazing source for create a great web magazine .

    This work fine with android ?

  2. 5

    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.

  3. 7

    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!

  4. 8

    Outstanding! How would one go about making it advance to specific page if one was linking to a specific page?

    Great work!

    • 9

      nm – I see – was hoping for in page animation but still outstanding.

    • 10

      is there an answere about the question above? “button to specific page if one was linking to a specific page”

      thx

  5. 11

    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

  6. 12

    I use Firefox to view, it’s OK. But chrome can’t view as Firefox :-s

  7. 14

    Amazing.. I love how flip board do their animation and same with this experiment.

  8. 15

    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

  9. 17

    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
    }

  10. 18

    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?

  11. 19

    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?

  12. 21

    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.

Comments are closed.