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

    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

  2. 2

    Awesome!! hope other browsers will support CSS 3D transforms and transitions!

  3. 3

    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!

  4. 5

    Wow, this is amazing. Love it :D Handy for a school newpaper website or a cool article website :D

  5. 6

    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

  6. 7

    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?

  7. 8

    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??

  8. 9

    can someone tell me how to allow controls inside page divs to recieve mouse events, i.e click event?

  9. 13

    Exceptional. A shame it’s just an experiment and not something going to be completed as I’d gladly pay for this and support.

  10. 18

    Hello, i’d like to know how to flip the pages when a certain div element (added by me) is clicked
    Thanks

Comments are closed.