<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Codrops &#187; jQuery</title>
	<atom:link href="http://tympanus.net/codrops/tag/jquery/feed/" rel="self" type="application/rss+xml" />
	<link>http://tympanus.net/codrops</link>
	<description>Useful resources and inspiration for creative minds</description>
	<lastBuildDate>Thu, 23 May 2013 13:36:15 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.5.1</generator>
		<item>
		<title>Fullscreen Layout with Page Transitions</title>
		<link>http://tympanus.net/codrops/2013/04/23/fullscreen-layout-with-page-transitions/</link>
		<comments>http://tympanus.net/codrops/2013/04/23/fullscreen-layout-with-page-transitions/#comments</comments>
		<pubDate>Tue, 23 Apr 2013 14:10:05 +0000</pubDate>
		<dc:creator>Mary Lou</dc:creator>
				<category><![CDATA[Playground]]></category>
		<category><![CDATA[CSS3]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[layout]]></category>
		<category><![CDATA[responsive]]></category>
		<category><![CDATA[transition]]></category>

		<guid isPermaLink="false">http://tympanus.net/codrops/?p=14783</guid>
		<description><![CDATA[A simple responsive layout with some fancy page transitions. The idea is to show four items initially and expand them. Some additional page transitions are added for inner items.]]></description>
				<content:encoded><![CDATA[<p><a href="http://tympanus.net/Development/FullscreenLayoutPageTransitions/"><img src="http://codropspz.tympanus.netdna-cdn.com/codrops/wp-content/uploads/2013/04/FullscreenLayoutPageTransitions.jpg" alt="FullscreenLayoutPageTransitions" width="580" height="315" class="alignnone size-full wp-image-14792" /></a></p>
<p><a class="demo" href="http://tympanus.net/Development/FullscreenLayoutPageTransitions/">View demo</a> <a class="download" href="http://tympanus.net/Development/FullscreenLayoutPageTransitions/FullscreenLayoutPageTransitions.zip">Download source</a></p>
<p>Today we&#8217;d like to share an experimental responsive layout with you. Initially, the layout shows four flexible boxes. When clicking on a box, it will expand to fullscreen and the others will scale down and fade out. When closing the current view, it will move back to the intial position while the other boxes come back up again. Another type of page transition can be seen on the works section where we will show a portfolio item by sliding in a panel from the bottom. The current view gets scaled down and disappears in the back.</p>
<p>All effects are done with CSS transitions and controled by applying classes with JavaScript. The whole layout is flexible and some media queries are added to size down things for smaller screens. </p>
<div class="ct-special-box"><strong>Please note: this only works as intended in browsers that support the respective CSS properties.</strong></div>
<p>The beautiful illustrations used in the works section of the demo are by talented <a href="http://dribbble.com/isaac317/click">Isaac Montemayor</a>. </p>
<p>Let&#8217;s take a look at some screenshots:</p>
<p><img src="http://codropspz.tympanus.netdna-cdn.com/codrops/wp-content/uploads/2013/04/FullscreenLayoutPageTransitions01.jpg" alt="FullscreenLayoutPageTransitions01" width="580" height="340" class="alignnone size-full wp-image-14785" /></p>
<p>The initial screen has the four flexible boxes. Resize the browser window to see them adapting fluidly. </p>
<p><img src="http://codropspz.tympanus.netdna-cdn.com/codrops/wp-content/uploads/2013/04/FullscreenLayoutPageTransitions02.jpg" alt="FullscreenLayoutPageTransitions02" width="580" height="340" class="alignnone size-full wp-image-14786" /></p>
<p>When clicking on a box, it get&#8217;s expanded to fullscreen.</p>
<p><img src="http://codropspz.tympanus.netdna-cdn.com/codrops/wp-content/uploads/2013/04/FullscreenLayoutPageTransitions03.jpg" alt="FullscreenLayoutPageTransitions03" width="580" height="340" class="alignnone size-full wp-image-14787" /></p>
<p>The view of a box that is expanded. A content are is revealed and we add a scroll to it when needed.</p>
<div class="ct-ad-article-wrapper ct-ad-article-wrapper-in"><div class="ct-ad-article"><img class="ct-ad-img" src="http://codropspz.tympanus.netdna-cdn.com/codrops/wp-content/themes/codropstheme02/images/advertisement.jpg" /><div id="bsap_1279993" class="bsarocks bsap_af25dfd2f1908889af7a1aa5f4dcbd9e"></div><div style="clear:both;"></div></div></div>
<p><img src="http://codropspz.tympanus.netdna-cdn.com/codrops/wp-content/uploads/2013/04/FullscreenLayoutPageTransitions04.jpg" alt="FullscreenLayoutPageTransitions04" width="580" height="340" class="alignnone size-full wp-image-14788" /></p>
<p>In the works section, we add a thumbnail grid which will reveal a details panel once we click on an item. The page transition here is the new item sliding in from the bottom and the old view scaling down and disappearing in the back.</p>
<p><img src="http://codropspz.tympanus.netdna-cdn.com/codrops/wp-content/uploads/2013/04/FullscreenLayoutPageTransitions05.jpg" alt="FullscreenLayoutPageTransitions05" width="580" height="340" class="alignnone size-full wp-image-14789" /></p>
<p>The navigation through the items has the same page transition. When we close the item view, it will transition back down and the works view will scale back up again.</p>
<p>We hope you like this little experiment and find it inspiring!</p>
<div class="ct-github-link"><a href="https://github.com/codrops/FullscreenLayoutPageTransitions">Find this project on Github</a></div>
<p><a class="demo" href="http://tympanus.net/Development/FullscreenLayoutPageTransitions/">View demo</a> <a class="download" href="http://tympanus.net/Development/FullscreenLayoutPageTransitions/FullscreenLayoutPageTransitions.zip">Download source</a></p>
]]></content:encoded>
			<wfw:commentRss>http://tympanus.net/codrops/2013/04/23/fullscreen-layout-with-page-transitions/feed/</wfw:commentRss>
		<slash:comments>82</slash:comments>
		</item>
		<item>
		<title>App Showcase with Grid Overlay</title>
		<link>http://tympanus.net/codrops/2013/04/01/app-showcase-with-grid-overlay/</link>
		<comments>http://tympanus.net/codrops/2013/04/01/app-showcase-with-grid-overlay/#comments</comments>
		<pubDate>Mon, 01 Apr 2013 13:11:54 +0000</pubDate>
		<dc:creator>Mary Lou</dc:creator>
				<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[3d]]></category>
		<category><![CDATA[CSS3]]></category>
		<category><![CDATA[grid]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[overlay]]></category>

		<guid isPermaLink="false">http://tympanus.net/codrops/?p=14621</guid>
		<description><![CDATA[A tutorial about creating a simple grid overlay with subtle transitions for an app showcase. ]]></description>
				<content:encoded><![CDATA[<p><a href="http://tympanus.net/Tutorials/AppShowcase/"><img src="http://codropspz.tympanus.netdna-cdn.com/codrops/wp-content/uploads/2013/03/AppShowcase.jpg" alt="App Showcase with Grid Overlay" width="580" height="315" class="alignnone size-full wp-image-14631" /></a></p>
<p><a class="demo" href="http://tympanus.net/Tutorials/AppShowcase/">View demo</a> <a class="download" href="http://tympanus.net/Tutorials/AppShowcase/AppShowcase.zip">Download source</a></p>
<p>Today we will be creating a little app showcase with a neat effect. The idea is to show a mobile device with a screenshot of an app and when clicking on the device, a grid appears, showing some more screenshots. The effect is very subtle: the device moves back and the grid fades in and scales up. When clicking on another screenshot, the device image gets updated and the grid disappears again. </p>
<div class="ct-special-box"><strong>Please note: this only works as intended in browsers that support the respective CSS properties.</strong></div>
<p>The beautiful <a href="http://dribbble.com/shots/990850-Minimal-iPhone-5-PSD-Free-Template-Updated">iPhone mockup</a> used in the demo is by <a href="http://dribbble.com/shod4n">Jakub Kejha</a></p>
<p>Let&#8217;s get started with the markup.</p>
<h3>The Markup</h3>
<p>The HTML will consist of a main wrapper that contains a heading, a division for the device and a division for the grid:</p>
<pre class="brush:html">
&lt;div id="ac-wrapper" class="ac-wrapper"&gt;
	&lt;h2&gt;Weatherous &lt;span&gt;Concept &amp; UI Design&lt;/span&gt;&lt;/h2&gt;
	&lt;div class="ac-device"&gt;
		&lt;a href="#"&gt;&lt;img src="images/screen1.jpg"/&gt;&lt;/a&gt;
		&lt;h3 class="ac-title"&gt;Gentrify small batch umami retro vegan&lt;/h3&gt;
	&lt;/div&gt;
	&lt;div class="ac-grid"&gt;
		&lt;a href="#"&gt;&lt;img src="images/screen1.jpg"/&gt;&lt;span&gt;Gentrify small batch umami retro vegan&lt;/span&gt;&lt;/a&gt;
		&lt;a href="#"&gt;&lt;img src="images/screen2.jpg"/&gt;&lt;span&gt;Chambray squid semiotics&lt;/span&gt;&lt;/a&gt;
		&lt;a href="#"&gt;&lt;img src="images/screen3.jpg"/&gt;&lt;span&gt;Fashion axe blue bottle&lt;/span&gt;&lt;/a&gt;
		&lt;a href="#"&gt;&lt;img src="images/screen4.jpg"/&gt;&lt;span&gt;Photo booth single-origin coffee&lt;/span&gt;&lt;/a&gt;
		&lt;a href="#"&gt;&lt;img src="images/screen5.jpg"/&gt;&lt;span&gt;Flexitarian synth keytar blog master&lt;/span&gt;&lt;/a&gt;
		&lt;a href="#"&gt;&lt;img src="images/screen6.jpg"/&gt;&lt;span&gt;Next level retro flexitarian freegan&lt;/span&gt;&lt;/a&gt;
		&lt;a href="#"&gt;&lt;img src="images/screen7.jpg"/&gt;&lt;span&gt;Pour-over superious meggings terry&lt;/span&gt;&lt;/a&gt;
		&lt;a href="#"&gt;&lt;img src="images/screen8.jpg"/&gt;&lt;span&gt;Seitan william vinyl chillwave&lt;/span&gt;&lt;/a&gt;
	&lt;/div&gt;
&lt;/div&gt;
</pre>
<p>Once we click on a grid item, we will update the content of the device container. We will also make the span for each grid item appear on hover.</p>
<p>Let&#8217;s style everything.</p>
<div class="ct-ad-article-wrapper ct-ad-article-wrapper-in"><div class="ct-ad-article"><img class="ct-ad-img" src="http://codropspz.tympanus.netdna-cdn.com/codrops/wp-content/themes/codropstheme02/images/advertisement.jpg" /><div id="bsap_1279993" class="bsarocks bsap_af25dfd2f1908889af7a1aa5f4dcbd9e"></div><div style="clear:both;"></div></div></div>
<h3>The CSS</h3>
<p><em>Note that the CSS will not contain any vendor prefixes, but you will find them in the files.</em><br />
<em>In this tutorial we will be going through the style of <a href="http://tympanus.net/Tutorials/AppShowcase/">demo 1</a>.</em></p>
<p>So let&#8217;s start with the main wrapper. This will be the container that will have perspective. The origin will not be in the center but a bit more up:</p>
<pre class="brush:css">
.ac-wrapper {
	width: 100%;
	position: relative;
	perspective: 1000px;
	perspective-origin: 50% 25%;
}
</pre>
<p>The heading will be positioned absolutely on the left side of the device:</p>
<pre class="brush:css">
.ac-wrapper h2 {
	top: 20%;
	width: 50%;
	position: absolute;
	font-weight: 300;
	font-size: 4em;
	text-align: right;
	padding: 0 180px 0 50px;
}
</pre>
<p>Let&#8217;s give a slightly different look to the span:</p>
<pre class="brush:css">
.ac-wrapper h2 span {
	display: block;
	font-size: 60%;
	color: #c0c0c0;
}
</pre>
<p>The device will have the iPhone mockup as a background image and we will set the right dimensions. This container will need to preserve the 3D transforms and we&#8217;ll add a transition to it. Later, we&#8217;ll define a &#8220;transition classes&#8221; that will contain the properties for the altered states.</p>
<pre class="brush:css">
.ac-device {
	background: url(../images/iPhone.png) no-repeat;
	width: 288px;
	height: 611px;
	margin: 0 auto;
	position: relative;
	transition: all 0.3s ease;
	transform-style: preserve-3d;
}
</pre>
<p>The screenshot will be inside of an anchor and we&#8217;ll set the dimensions here and position it to fit into the mockup:</p>
<pre class="brush:css">
.ac-device a {
	height: 440px;
	width: 249px;
	display: inline-block;
	margin: 85px 0 0 20px;
}

.ac-device a img {
	display: block;
}
</pre>
<p>The title for each screenshot once it&#8217;s in the mockup view will be positioned absolutely on the right side of the device:</p>
<pre class="brush:css">
.ac-device h3 {
	position: absolute;
	font-size: 2.5em;
	left: 100%;
	width: 100%;
	top: 60%;
	margin-left: 30px;
	font-weight: 300;
	color: #888;
}
</pre>
<p>Now, let&#8217;s style the grid. We want to display a total of eight items so a row will have four items. Let&#8217;s set a fitting width, make it absolute and center it by setting a negative left margin (half of its width) and a left value of 50%. The initial opacity is 0 and since the grid is displayed and covering the device, we&#8217;ll set the pointer events to <code>none</code> so that we can&#8217;t click on it when it&#8217;s invisible. We&#8217;ll also add a transition and translate it -350px on the Z axis:</p>
<pre class="brush:css">
.ac-grid {
	position: absolute;
	width: 620px;
	left: 50%;
	margin-left: -310px;
	height: 100%;
	z-index: 1000;
	top: 0;
	opacity: 0;
	pointer-events: none;
	transform-style: preserve-3d;
	transition: all 0.3s ease;
	transform: translateZ(-350px);
}
</pre>
<p>The anchors in the grid will be floated left and the images inside will be set to 100% width. This will come in handy later on when we apply some media queries:</p>
<pre class="brush:css">
.ac-grid a {
	width: 145px;
	display: block;
	position: relative;
	float: left;
	margin: 10px 5px;
	cursor: pointer;
}

.ac-grid a img {
	display: block;
	width: 100%;
}
</pre>
<p>The span for the description will be positioned absolutely on top of the anchor and we&#8217;ll fade it in and move it a bit on hover:</p>
<pre class="brush:css">
.ac-grid a span {
	position: absolute;
	height: 100%;
	width: 100%;
	left: 0;
	top: 0;
	text-transform: uppercase;
	padding: 3em 1em 0;
	z-index: 100;
	color: #ddd;
	background: rgba(0,0,0,0.4);
	font-weight: 700;
	opacity: 0;
	transform: translateY(-5px);
	transition: all 0.2s ease;
}

.ac-grid a:hover span {
	opacity: 1;
	transform: translateY(0);
}
</pre>
<p>Next, we&#8217;ll define the &#8220;transition classes&#8221;. When we click on the device, we&#8217;ll apply a class to the wrapper which will trigger the fading in and scaling up of the grid and the moving back of the device:</p>
<pre class="brush:css">
.ac-wrapper.ac-gridview .ac-device {
	transform: translateZ(-350px);
	opacity: 0.6;
}

.ac-wrapper.ac-gridview .ac-grid {
	transform: translateZ(0px);
	opacity: 1;
	pointer-events: auto;
}
</pre>
<p>Once the grid is there, we also set the pointer-events to <code>auto</code> again.</p>
<p>Our layout has some absolutely positioned elements and we&#8217;ll need to take care of them on smaller screens. The idea is that we will switch the main heading to the right side first and then center everything once the screen is very small.  The second media query takes care of the grid structure. Here we will set a fluid width for both, the grid and the anchors:</p>
<pre class="brush:css">
@media screen and (max-width: 63.875em) {
	.ac-wrapper { 
		font-size: 60%; 
		width: 100%; 
		padding: 0 20px;
	}

	.ac-device {
		margin: 0;
		width: 100%;
	}

	.ac-device h3 { 
		width: 50%;
		left: 290px;
	}

	.ac-wrapper h2 { 
		left: 308px; 
		padding: 0; 
		text-align: left; 
		margin-left: 30px;
	}
}

@media screen and (max-width: 39.8125em) {
	.ac-grid {
		width: 90%;
		left: 5%;
		margin-left: 0;
		padding-top: 150px;
	}

	.ac-grid a {
		width: 22%;
	}
}


@media screen and (max-width: 35.6875em) {
	.ac-wrapper {
		padding: 0 20px 100px;
	}

	.ac-wrapper h2 { 
		width: 100%;
		text-align: center;
		margin: 0 0 1em;
		top: 0;
		left: auto;
		position: relative;
	}

	.ac-device {
		margin: 0 auto;
		width: 288px;
	}

	.ac-device h3 {
		position: relative;
		margin: 0;
		left: auto;
		width: 100%;
		top: 100px;
		display: block;
		text-align: center;
	}
}
</pre>
<p>And that&#8217;s all the style! Let&#8217;s take a look at the JavaScript.</p>
<h3>The JavaScript</h3>
<p>Let&#8217;s start by caching some elements and initialize some variables:</p>
<pre class="brush:js">
	var $el = $( '#ac-wrapper' ),
		// device element
		$device = $el.find( '.ac-device' ),
		// the device image wrapper
		$trigger = $device.children( 'a:first' ),
		// the screens
		$screens = $el.find( '.ac-grid > a' ),
		// the device screen image
		$screenImg = $device.find( 'img' ),
		// the device screen title
		$screenTitle = $device.find( '.ac-title' ),
		// HTML Body element
		$body = $( 'body' ); 	
</pre>
<p>We will bind the events to the device&#8217;s image wrapper (anchor) and to the screen elements.</p>
<pre class="brush:js">
	function init() {
		// show grid
		$trigger.on( 'click', showGrid );
		// when a grid´s screen is clicked, show the respective image on the device
		$screens.on( 'click', function() {
			showScreen( $( this ) );
			return false;
		} );
	}
</pre>
<p>When the device&#8217;s image is clicked, the grid is shown. For this to happen the class &#8220;ac-gridview&#8221; has to be added to the ac-wrapper element:</p>
<pre class="brush:js">
	function showGrid() {
		$el.addClass( 'ac-gridview' );
		// clicking somewhere else on the page closes the grid view
		$body.off( 'click' ).on( 'click', function() { showScreen(); } );
		return false;
	}
</pre>
<p>When a screen element is clicked we remove the &#8220;ac-gridview&#8221; class from the ac-wrapper element, and update both, image source and title on the respective elements:</p>
<pre class="brush:js">
	function showScreen( $screen ) {
		$el.removeClass( 'ac-gridview' );
		if( $screen ) {
			// update image and title on the device
			$screenImg.attr( 'src', $screen.find( 'img' ).attr( 'src' ) );
			$screenTitle.text( $screen.find( 'span' ).text() );
		}
	}
</pre>
<p>For the <a href="http://tympanus.net/Tutorials/AppShowcase/">third demo</a> we also want to offer the possibility to navigate through the screenshots without having to open the grid. Depending to the direction we are navigating, the next screen will either scale up / fade in (navigating to the next screen) or move up / fade in (navigating to the previous screen). The same logic applies to the current screenshot. In order for this to work, we need to add the next/previous screen&#8217;s image to the DOM right before the current screen&#8217;s image (both images being absolute). When the transition ends we remove the old one: </p>
<pre class="brush:js">
	function navigate( direction ) {

		// if currently animating return
		if( animating ) {
			return false;
		}

		animating = true;
		
		// update current
		if( direction === 'next' ) {
			current = current < screensCount - 1 ? ++current : 0;
		}
		else if( direction === 'prev' ) {
			current = current > 0 ? --current : screensCount - 1;
		}
		
		// next screen to show
		var $nextScreen = $screens.eq( current );

		// if css transitions support:
		if( support ) {

			// append new image to the device and set the transition and initial style
			var $nextScreenImg = $( '<img src="' + $nextScreen.find( 'img' ).attr( 'src' ) + '"></img>' ).css( {
				transition : 'all 0.5s ease',
				opacity : 0,
				transform : direction === 'next' ? 'scale(0.9)' : 'translateY(100px)'
			} ).insertBefore( $screenImg );

			// update title
			$screenTitle.text( $nextScreen.find( 'span' ).text() );

			setTimeout( function() {

				// current image fades out / new image fades in
				$screenImg.css( {
					opacity : 0,
					transform : direction === 'next' ? 'translateY(100px)' : 'scale(0.9)' 
				} ).on( transEndEventName, function() { $( this ).remove(); } );

				$nextScreenImg.css( {
					opacity : 1,
					transform : direction === 'next' ? 'scale(1)' : 'translateY(0px)' 
				} ).on( transEndEventName, function() {
					$screenImg = $( this ).off( transEndEventName );
					animating = false;
				} );

			}, 25 );

		}
		else {
			// update image and title on the device
			$screenImg.attr( 'src', $nextScreen.find( 'img' ).attr( 'src' ) );
			$screenTitle.text( $nextScreen.find( 'span' ).text() );
			animating = false;
		}

	}
</pre>
<p>This navigation concept was introduced by <a href="https://twitter.com/youyuxi">Evan You</a> and you can check it out <a href="http://sketch.evanyou.me/layers/">here</a>, or <a href="http://www.youtube.com/watch?v=8wzoGRTPEQM">watch the video</a>.</p>
<p>And that&#8217;s all! We hope you enjoyed this tutorial and find it inspiring!</p>
<p><a class="demo" href="http://tympanus.net/Tutorials/AppShowcase/">View demo</a> <a class="download" href="http://tympanus.net/Tutorials/AppShowcase/AppShowcase.zip">Download source</a></p>
]]></content:encoded>
			<wfw:commentRss>http://tympanus.net/codrops/2013/04/01/app-showcase-with-grid-overlay/feed/</wfw:commentRss>
		<slash:comments>27</slash:comments>
		</item>
		<item>
		<title>Thumbnail Grid with Expanding Preview</title>
		<link>http://tympanus.net/codrops/2013/03/19/thumbnail-grid-with-expanding-preview/</link>
		<comments>http://tympanus.net/codrops/2013/03/19/thumbnail-grid-with-expanding-preview/#comments</comments>
		<pubDate>Tue, 19 Mar 2013 12:15:34 +0000</pubDate>
		<dc:creator>Mary Lou</dc:creator>
				<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[CSS3]]></category>
		<category><![CDATA[grid]]></category>
		<category><![CDATA[images]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[preview]]></category>
		<category><![CDATA[thumbnail]]></category>

		<guid isPermaLink="false">http://tympanus.net/codrops/?p=14530</guid>
		<description><![CDATA[A tutorial on how to create a thumbnail grid with an expanding image preview similar to the effect seen on Google Images.]]></description>
				<content:encoded><![CDATA[<p><a href="http://tympanus.net/Tutorials/ThumbnailGridExpandingPreview/"><img src="http://codropspz.tympanus.netdna-cdn.com/codrops/wp-content/uploads/2013/03/ThumbnailGridExpandingPreview.jpg" alt="Thumbnail Grid with Expanding Preview" width="580" height="315" class="alignnone size-full wp-image-14533" /></a></p>
<p><a class="demo" href="http://tympanus.net/Tutorials/ThumbnailGridExpandingPreview/">View demo</a> <a class="download" href="http://tympanus.net/Tutorials/ThumbnailGridExpandingPreview/ThumbnailGridExpandingPreview.zip">Download source</a></p>
<p>If you have searched images on Google recently, you might have noticed the interesting expanding preview for a larger image when you click on a thumbnail. It&#8217;s a really nice effect and it is very practical, making a search much easier. Today we want to show you how to create a similar effect on a thumbnail grid. The idea is to open a preview when clicking on a thumbnail and to show a larger image and some other content like a title, a description and a link. </p>
<p>The interesting part is to calculate the correct preview height and to scroll the page to the right position. We&#8217;ll expand the preview in a way so that we can see the respective thumbnail row and cover the rest of the remaining page. Note that we don&#8217;t use very large images for the preview in the demo so you might see a lot of empty space on large monitors. </p>
<p>The demo features some amazing artwork by <a href="http://cargocollective.com/jaimemartinez">Jaime Martinez</a>.</p>
<p>So let&#8217;s start! </p>
<h3>The Markup</h3>
<p>Initially, we need a thumbnail grid for which we will use an unordered list. Each list item will contain an anchor which will have several data attributes: </p>
<pre class="brush:html">
&lt;ul id="og-grid" class="og-grid"&gt;
	&lt;li&gt;
		&lt;a href="http://cargocollective.com/jaimemartinez/" data-largesrc="images/1.jpg" data-title="Azuki bean" data-description="Swiss chard pumpkin bunya nuts maize plantain aubergine napa cabbage soko coriander sweet pepper water spinach winter purslane shallot tigernut lentil beetroot."&gt;
			&lt;img src="images/thumbs/1.jpg" alt="img01"/&gt;
		&lt;/a&gt;
	&lt;/li&gt;
	&lt;li&gt;
		&lt;a href="http://cargocollective.com/jaimemartinez/" data-largesrc="images/2.jpg" data-title="Veggies sunt bona vobis" data-description="Komatsuna prairie turnip wattle seed artichoke mustard horseradish taro rutabaga ricebean carrot black-eyed pea turnip greens beetroot yarrow watercress kombu."&gt;
			&lt;img src="images/thumbs/2.jpg" alt="img02"/&gt;
		&lt;/a&gt;
	&lt;/li&gt;
	&lt;li&gt;&lt;!-- ... --&gt;&lt;/li&gt;
	&lt;!-- ... --&gt;
&lt;/ul&gt;
</pre>
<p>The <code>href</code> value will be used to construct the link in the preview description (this also comes in handy when JavaScript is disabled). The <code>data-largesrc</code> attribute contains the path to the larger image. <code>data-title</code> and <code>data-description</code> contain the title and description, respectively.</p>
<p>When we click on a thumbnail, we want a preview element to appear under the list item. For that we will need to insert an element into the grid. In fact, we will use the list item itself and add the preview element after the anchor:</p>
<pre class="brush:html">
&lt;li&gt;

	&lt;a href="http://cargocollective.com/jaimemartinez/" data-largesrc="images/2.jpg" data-title="Veggies sunt bona vobis" data-description="Komatsuna prairie turnip wattle seed artichoke mustard horseradish taro rutabaga ricebean carrot black-eyed pea turnip greens beetroot yarrow watercress kombu."&gt;
		&lt;img src="images/thumbs/2.jpg" alt="img02"/&gt;
	&lt;/a&gt;
	
	&lt;div class="og-expander"&gt;
		&lt;div class="og-expander-inner"&gt;
			&lt;span class="og-close"&gt;&lt;/span&gt;
			&lt;div class="og-fullimg"&gt;
				&lt;div class="og-loading"&gt;&lt;/div&gt;
				&lt;img src="images/2.jpg"&gt;
			&lt;/div&gt;
			&lt;div class="og-details"&gt;
				&lt;h3&gt;Veggies sunt bona vobis&lt;/h3&gt;
				&lt;p&gt;Komatsuna prairie turnip wattle seed artichoke mustard horseradish taro rutabaga ricebean carrot black-eyed pea turnip greens beetroot yarrow watercress kombu.&lt;/p&gt;
				&lt;a href="http://cargocollective.com/jaimemartinez/"&gt;Visit website&lt;/a&gt;
			&lt;/div&gt;
		&lt;/div&gt;
	&lt;/div&gt;

&lt;/li&gt;
</pre>
<p>Let&#8217;s style everything!</p>
<div class="ct-ad-article-wrapper ct-ad-article-wrapper-in"><div class="ct-ad-article"><img class="ct-ad-img" src="http://codropspz.tympanus.netdna-cdn.com/codrops/wp-content/themes/codropstheme02/images/advertisement.jpg" /><div id="bsap_1279993" class="bsarocks bsap_af25dfd2f1908889af7a1aa5f4dcbd9e"></div><div style="clear:both;"></div></div></div>
<h3>The CSS</h3>
<p><em>Note that the CSS will not contain any vendor prefixes, but you will find them in the files.</em></p>
<p>So, let&#8217;s start with the thumbnail grid. It will be full width and we&#8217;ll center the text. In this case this will mean that it will center the thumbnails because we&#8217;ll set them to <code>display: inline-block</code>:</p>
<pre class="brush:css">
.og-grid {
	list-style: none;
	padding: 20px 0;
	margin: 0 auto;
	text-align: center;
	width: 100%;
}

.og-grid li {
	display: inline-block;
	margin: 10px 5px 0 5px;
	vertical-align: top;
	height: 250px;
}
</pre>
<p>The links and images will be displayed as block elements and we&#8217;ll remove some default styling:</p>
<pre class="brush:css">
.og-grid li > a,
.og-grid li > a img {
	border: none;
	outline: none;
	display: block;
	position: relative;
}
</pre>
<p>When we click on an item, we will give a special class to the respective list item which will be called <code>og-expanded</code>. We&#8217;ll add a little arrow as pseudo-element to the anchor:</p>
<pre class="brush:css">
.og-grid li.og-expanded > a::after {
	top: auto;
	border: solid transparent;
	content: " ";
	height: 0;
	width: 0;
	position: absolute;
	pointer-events: none;
	border-bottom-color: #ddd;
	border-width: 15px;
	left: 50%;
	margin: -20px 0 0 -15px;
}
</pre>
<p>The preview itself will have the class <code>og-expander</code> and we&#8217;ll position that element absolutely. The initial height of the preview will be 0 and we&#8217;ll set the overflow to hidden:</p>
<pre class="brush:css">
.og-expander {
	position: absolute;
	background: #ddd;
	top: auto;
	left: 0;
	width: 100%;
	margin-top: 10px;
	text-align: left;
	height: 0;
	overflow: hidden;
}

.og-expander-inner {
	padding: 50px 30px;
	height: 100%;
}

</pre>
<p>The inner division will have some paddings and a height of 100%.</p>
<p>The cross for closing the preview will be created using pseudo-elements, i.e. two rotated lines:</p>
<pre class="brush:css">
.og-close {
	position: absolute;
	width: 40px;
	height: 40px;
	top: 20px;
	right: 20px;
	cursor: pointer;
}

.og-close::before,
.og-close::after {
	content: '';
	position: absolute;
	width: 100%;
	top: 50%;
	height: 1px;
	background: #888;
	transform: rotate(45deg);
}

.og-close::after {
	transform: rotate(-45deg);
}

.og-close:hover::before,
.og-close:hover::after {
	background: #333;
}
</pre>
<p>The wrappers for the image and for the details will be 50% wide and we&#8217;ll make them float next to each other:</p>
<pre class="brush:css">
.og-fullimg,
.og-details {
	width: 50%;
	float: left;
	height: 100%;
	overflow: hidden;
	position: relative;
}
</pre>
<p>The details wrapper will have some padding and we&#8217;ll center the image inside of the image wrapper by setting the text-align to center and the image itself to <code>display: inline-block</code>. The image will also have a max-height and max-width of 100% so that it adjusts its size to the surrounding container:</p>
<pre class="brush:css">
.og-details {
	padding: 0 40px 0 20px;
}

.og-fullimg {
	text-align: center;
}

.og-fullimg img {
	display: inline-block;
	max-height: 100%;
	max-width: 100%;
}

</pre>
<p>Let&#8217;s style the text elements and the link:</p>
<pre class="brush:css">
.og-details h3 {
	font-weight: 300;
	font-size: 52px;
	padding: 40px 0 10px;
	margin-bottom: 10px;
}

.og-details p {
	font-weight: 400;
	font-size: 16px;
	line-height: 22px;
	color: #999;
}

.og-details a {
	font-weight: 700;
	font-size: 16px;
	color: #333;
	text-transform: uppercase;
	letter-spacing: 2px;
	padding: 10px 20px;
	border: 3px solid #333;
	display: inline-block;
	margin: 30px 0 0;
	outline: none;
}

.og-details a::before {
	content: '\2192';
	display: inline-block;
	margin-right: 10px;
}

.og-details a:hover {
	border-color: #999;
	color: #999;
}
</pre>
<p>The loading element will be in the same container as the image and we&#8217;ll not use any images but this CSS-only technique. We&#8217;ll create a little circle and set three box shadows: one for making the circle itself look a bit smoother and two for &#8220;copying&#8221; the element. Then we create an animation that will change the background color and the box shadow colors sequentially:</p>
<pre class="brush:css">
.og-loading {
	width: 20px;
	height: 20px;
	border-radius: 50%;
	background: #ddd;
	box-shadow: 0 0 1px #ccc, 15px 30px 1px #ccc, -15px 30px 1px #ccc;
	position: absolute;
	top: 50%;
	left: 50%;
	margin: -25px 0 0 -25px;
	animation: loader 0.5s infinite ease-in-out both;
}

@keyframes loader {
	0% { background: #ddd; }
	33% { background: #ccc; box-shadow: 0 0 1px #ccc, 15px 30px 1px #ccc, -15px 30px 1px #ddd; }
	66% { background: #ccc; box-shadow: 0 0 1px #ccc, 15px 30px 1px #ddd, -15px 30px 1px #ccc; }
}

</pre>
<p>Last, but not least, we&#8217;ll add two media queries for adjusting the text a bit and for hiding the full image once the screen gets so small that the preview image is not really useful anymore (we&#8217;ll also not load it in the JavaScript then).</p>
<pre class="brush:css">

@media screen and (max-width: 830px) {

	.og-expander h3 { font-size: 32px; }
	.og-expander p { font-size: 13px; }
	.og-expander a { font-size: 12px; }

}

@media screen and (max-width: 650px) {

	.og-fullimg { display: none; }
	.og-details { float: none; width: 100%; }
	
}
</pre>
<p>That&#8217;s all the style. Now, let&#8217;s take a look at the JavaScript.</p>
<h3>The JavaScript</h3>
<p>Let&#8217;s start by caching some elements and initializing some variables:</p>
<pre class="brush:js">
	// list of items
var $grid = $( '#og-grid' ),
	// the items
	$items = $grid.children( 'li' ),
	// current expanded item´s index
	current = -1,
	// position (top) of the expanded item
	// used to know if the preview will expand in a different row
	previewPos = -1,
	// extra amount of pixels to scroll the window
	scrollExtra = 0,
	// extra margin when expanded (between the preview element and the next item row)
	marginExpanded = 10,
	$window = $( window ), winsize,
	$body = $( 'html, body' ),
	// transitionend events
	transEndEventNames = {
		'WebkitTransition' : 'webkitTransitionEnd',
		'MozTransition' : 'transitionend',
		'OTransition' : 'oTransitionEnd',
		'msTransition' : 'MSTransitionEnd',
		'transition' : 'transitionend'
	},
	transEndEventName = transEndEventNames[ Modernizr.prefixed( 'transition' ) ],
	// support for csstransitions
	support = Modernizr.csstransitions,
	// default settings
	settings = {
		minHeight : 500,
		speed : 350,
		easing : 'ease'
	};
</pre>
<p>We will start by preloading all the images (thumbnails) in the grid. We then save the offset top and height for each item in the grid, get the current window&#8217;s size, and initialize some events: </p>
<pre class="brush:js">
	function init( config ) {
		
		// the settings..
		settings = $.extend( true, {}, settings, config );

		// preload all images
		$grid.imagesLoaded( function() {

			// save item´s size and offset
			saveItemInfo( true );
			// get window´s size
			getWinSize();
			// initialize some events
			initEvents();

		} );

	}

	// saves the item´s offset top and height (if saveheight is true)
	function saveItemInfo( saveheight ) {
		$items.each( function() {
			var $item = $( this );
			$item.data( 'offsetTop', $item.offset().top );
			if( saveheight ) {
				$item.data( 'height', $item.height() );
			}
		} );
	}

	function getWinSize() {
		winsize = { width : $window.width(), height : $window.height() };
	}
</pre>
<p>We will bind the click event for each item (anchor) and for the close button (when the item is opened). When we click on an item, the preview with the large image source and the details will be revealed or hidden if already shown. If we click the close button (cross) on the preview then this preview will be closed too.<br />
We are also binding the resize event for the window, where some values are reset and the preview gets closed (if opened).</p>
<pre class="brush:js">
	function initEvents() {
		
		// when clicking an item, show the preview with the item´s info and large image;
		// close the item if already expanded.
		// also close if clicking on the item´s cross
		$items.on( 'click', 'span.og-close', function() {
			hidePreview();
			return false;
		} ).children( 'a' ).on( 'click', function(e) {

			var $item = $( this ).parent();
			// check if item already opened
			current === $item.index() ? hidePreview() : showPreview( $item );
			return false;

		} );

		// on window resize get the window´s size again
		// reset some values..
		$window.on( 'debouncedresize', function() {
			
			scrollExtra = 0;
			previewPos = -1;
			// save item´s offset
			saveItemInfo();
			getWinSize();
			var preview = $.data( this, 'preview' );
			if( typeof preview != 'undefined' ) {
				hidePreview();
			}

		} );

	}
</pre>
<p>With the <em>showPreview</em> function we will basically initialize the Preview object, which in turn will expand and reveal the details and the large version of the image. If a Preview instance is already initialized then we will only update the preview with the new details (if the clicked item is in the same row as the current expanded item) or hide it and initialize / open a new one (if not in the same row).<br />
In order to check if the items are in the same row as the current preview, we use the offset top value of the items. </p>
<pre class="brush:js">
	function showPreview( $item ) {

		var preview = $.data( this, 'preview' ),
			// item´s offset top
			position = $item.data( 'offsetTop' );

		scrollExtra = 0;

		// if a preview exists and previewPos is different (different row) from item´s top, then close it
		if( typeof preview != 'undefined' ) {

			// not in the same row
			if( previewPos !== position ) {
				// if position > previewPos then we need to take the current preview´s height in consideration when scrolling the window
				if( position > previewPos ) {
					scrollExtra = preview.height;
				}
				hidePreview();
			}
			// same row
			else {
				preview.update( $item );
				return false;
			}
			
		}

		// update previewPos
		previewPos = position;
		// initialize new preview for the clicked item
		preview = $.data( this, 'preview', new Preview( $item ) );
		// expand preview overlay
		preview.open();

	}
</pre>
<p>The Preview object will have a reference to the currently displayed item (Preview.$item), and the index of the expanded item (Preview.expandedIdx). Note that the expanded item is not necessarily the displayed item. For instance if we click on a second item that is on the same row as the one clicked before then the Preview will be &#8220;reused&#8221; and the Preview.expandedIdx will not be the index of the Preview.$item. We need to keep the reference to the expanded item so that when the Preview is closed we know which item to &#8220;collapse&#8221;. </p>
<pre class="brush:js">
	// the preview obj / overlay
	function Preview( $item ) {
		this.$item = $item;
		this.expandedIdx = this.$item.index();
		this.create();
		this.update();
	}
</pre>
<p>As the Preview object is initialized we create the necessary structure where the item´s details will be rendered and we append it to the item:</p>
<pre class="brush:js">
	create : function() {
		// create Preview structure:
		this.$title = $( '&lt;h3&gt;&lt;/h3&gt;' );
		this.$description = $( '&lt;p&gt;&lt;/p&gt;' );
		this.$href = $( '&lt;a href="#"&gt;Visit website&lt;/a&gt;' );
		this.$details = $( '&lt;div class="og-details"&gt;&lt;/div&gt;' ).append( this.$title, this.$description, this.$href );
		this.$loading = $( '&lt;div class="og-loading"&gt;&lt;/div&gt;' );
		this.$fullimage = $( '&lt;div class="og-fullimg"&gt;&lt;/div&gt;' ).append( this.$loading );
		this.$closePreview = $( '&lt;span class="og-close"&gt;&lt;/span&gt;' );
		this.$previewInner = $( '&lt;div class="og-expander-inner"&gt;&lt;/div&gt;' ).append( this.$closePreview, this.$fullimage, this.$details );
		this.$previewEl = $( '&lt;div class="og-expander"&gt;&lt;/div&gt;' ).append( this.$previewInner );
		// append preview element to the item
		this.$item.append( this.getEl() );
		// set the transitions for the preview and the item
		if( support ) {
			this.setTransition();
		}
	}
</pre>
<p>Then we fill the previous structure with the item´s details (stored in data attributes and the href).<br />
The update function will also be used to just update the content of an existing preview.</p>
<pre class="brush:js">
	update : function( $item ) {

		// update with new item´s details 
		if( $item ) {
			this.$item = $item;
		}
		
		// if already expanded, remove class "og-expanded" from current item and add it to new item
		if( current !== -1 ) {
			var $currentItem = $items.eq( current );
			$currentItem.removeClass( 'og-expanded' );
			this.$item.addClass( 'og-expanded' );
			// position the preview correctly
			this.positionPreview();
		}

		// update current value
		current = this.$item.index();

		// update preview´s content
		var $itemEl = this.$item.children( 'a' ),
			eldata = {
				href : $itemEl.attr( 'href' ),
				largesrc : $itemEl.data( 'largesrc' ),
				title : $itemEl.data( 'title' ),
				description : $itemEl.data( 'description' )
			};

		this.$title.html( eldata.title );
		this.$description.html( eldata.description );
		this.$href.attr( 'href', eldata.href );

		var self = this;
		
		// remove the current image in the preview
		if( typeof self.$largeImg != 'undefined' ) {
			self.$largeImg.remove();
		}

		// preload large image and add it to the preview
		// for smaller screens we don´t display the large image (the last media query will hide the wrapper of the image)
		if( self.$fullimage.is( ':visible' ) ) {
			this.$loading.show();
			$( '&lt;img/&gt;' ).load( function() {
				self.$loading.hide();
				self.$largeImg = $( this ).fadeIn( 350 );
				self.$fullimage.append( self.$largeImg );
			} ).attr( 'src', eldata.largesrc );	
		}

	}
</pre>
<p>To reveal the preview we need to set the height of the Preview element and also of the item (to push down the items below). The height of the preview will be the window´s height minus the height of the grid item. To avoid cases where that height could be too small we add the option &#8220;minHeight&#8221; where we can specify the minimum height needed for the preview element.<br />
As the preview opens we will want to scroll the window so that the preview is completely visible (and if possible, also the item).</p>
<pre class="brush:js">
	open : function() {

		setTimeout( $.proxy( function() {	
			// set the height for the preview and the item
			this.setHeights();
			// scroll to position the preview in the right place
			this.positionPreview();
		}, this ), 25 );

	}

	setHeights : function() {

		var self = this,
			onEndFn = function() {
				if( support ) {
					self.$item.off( transEndEventName );
				}
				self.$item.addClass( 'og-expanded' );
			};

		this.calcHeight();
		this.$previewEl.css( 'height', this.height );
		this.$item.css( 'height', this.itemHeight ).on( transEndEventName, onEndFn );

		if( !support ) {
			onEndFn.call();
		}

	}

	calcHeight : function() {

		var heightPreview = winsize.height - this.$item.data( 'height' ) - marginExpanded,
			itemHeight = winsize.height;

		if( heightPreview < settings.minHeight ) {
			heightPreview = settings.minHeight;
			itemHeight = settings.minHeight + this.$item.data( 'height' ) + marginExpanded;
		}

		this.height = heightPreview;
		this.itemHeight = itemHeight;

	}

	positionPreview : function() {

		// scroll page
		// case 1 : preview height + item height fits in window´s height
		// case 2 : preview height + item height does not fit in window´s height and preview height is smaller than window´s height
		// case 3 : preview height + item height does not fit in window´s height and preview height is bigger than window´s height
		var position = this.$item.data( 'offsetTop' ),
			previewOffsetT = this.$previewEl.offset().top - scrollExtra,
			scrollVal = this.height + this.$item.data( 'height' ) + marginExpanded <= winsize.height ? position : this.height < winsize.height ? previewOffsetT - ( winsize.height - this.height ) : previewOffsetT;
		
		$body.animate( { scrollTop : scrollVal }, settings.speed );

	}
</pre>
<p>When closing the preview we reset the heights of the preview element and the expanded item. Once this is done, the preview element / structure gets removed from the DOM.</p>
<pre class="brush:js">
	close : function() {

		var self = this,
			onEndFn = function() {
				if( support ) {
					$( this ).off( transEndEventName );
				}
				self.$item.removeClass( 'og-expanded' );
				self.$previewEl.remove();
			};

		setTimeout( $.proxy( function() {

			if( typeof this.$largeImg !== 'undefined' ) {
				this.$largeImg.fadeOut( 'fast' );
			}
			this.$previewEl.css( 'height', 0 );
			// the current expanded item (might be different from this.$item)
			var $expandedItem = $items.eq( this.expandedIdx );
			$expandedItem.css( 'height', $expandedItem.data( 'height' ) ).on( transEndEventName, onEndFn );

			if( !support ) {
				onEndFn.call();
			}

		}, this ), 25 );
		
		return false;

	}
</pre>
<p>And that's it! We hope you enjoyed this tutorial and find it inspiring! </p>
<p><!--div class="ct-github-link"><a href="https://github.com/codrops/ThumbnailGridExpandingPreview">Find this project on Github</a></div-->
<p><a class="demo" href="http://tympanus.net/Tutorials/ThumbnailGridExpandingPreview/">View demo</a> <a class="download" href="http://tympanus.net/Tutorials/ThumbnailGridExpandingPreview/ThumbnailGridExpandingPreview.zip">Download source</a></p>
]]></content:encoded>
			<wfw:commentRss>http://tympanus.net/codrops/2013/03/19/thumbnail-grid-with-expanding-preview/feed/</wfw:commentRss>
		<slash:comments>191</slash:comments>
		</item>
		<item>
		<title>Flipping Circle Slideshow</title>
		<link>http://tympanus.net/codrops/2013/01/28/flipping-circle-slideshow/</link>
		<comments>http://tympanus.net/codrops/2013/01/28/flipping-circle-slideshow/#comments</comments>
		<pubDate>Mon, 28 Jan 2013 13:09:38 +0000</pubDate>
		<dc:creator>Mary Lou</dc:creator>
				<category><![CDATA[Playground]]></category>
		<category><![CDATA[3d]]></category>
		<category><![CDATA[CSS3]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[plugin]]></category>
		<category><![CDATA[slideshow]]></category>
		<category><![CDATA[transform]]></category>

		<guid isPermaLink="false">http://tympanus.net/codrops/?p=13951</guid>
		<description><![CDATA[A simple circular slideshow where we flip the image in order to navigate. ]]></description>
				<content:encoded><![CDATA[<p><a href="http://tympanus.net/Development/CircleFlipSlideshow/"><img src="http://codropspz.tympanus.netdna-cdn.com/codrops/wp-content/uploads/2013/01/FlippingCircleSlideshow.jpg" alt="Flipping Circle Slideshow" width="580" height="315" class="alignnone size-full wp-image-13955" /></a></p>
<p><a class="demo" href="http://tympanus.net/Development/CircleFlipSlideshow/">View demo</a> <a class="download" href="http://tympanus.net/Development/CircleFlipSlideshow/CircleFlipSlideshow.zip">Download source</a></p>
<p>Today we want to share a simple and fun circular slideshow with you. It&#8217;s an experimental concept and the idea is to flip a circle in a specific angle depending on which spot of the circle we click. There are three different possibilities for each side: top, middle and bottom. For example, when clicking on the top right part of the image, the circle will flip in the associated angle, making it look as if we press down that part and reveal the next image that is on the back face of the circle.</p>
<p>The demo features illustrations by <a href="http://cargocollective.com/isaac317">Isaac Montemayor</a>. See his works on <a href="http://dribbble.com/isaac317">Dribbble</a> or on his <a href="http://cargocollective.com/isaac317">website</a>.</p>
<p>This is how the structure looks like:</p>
<pre class="brush:html">
&lt;div id="fc-slideshow" class="fc-slideshow"&gt;
	&lt;ul class="fc-slides"&gt;
		&lt;li&gt;&lt;img src="images/1.jpg" /&gt;&lt;h3&gt;Hot&lt;/h3&gt;&lt;/li&gt;
		&lt;li&gt;&lt;img src="images/2.jpg" /&gt;&lt;h3&gt;Cold&lt;/h3&gt;&lt;/li&gt;
		&lt;li&gt;&lt;img src="images/3.jpg" /&gt;&lt;h3&gt;Light&lt;/h3&gt;&lt;/li&gt;
		&lt;li&gt;&lt;img src="images/4.jpg" /&gt;&lt;h3&gt;Dark&lt;/h3&gt;&lt;/li&gt;
		&lt;li&gt;&lt;img src="images/5.jpg" /&gt;&lt;h3&gt;Soft&lt;/h3&gt;&lt;/li&gt;
		&lt;li&gt;&lt;img src="images/6.jpg" /&gt;&lt;h3&gt;Hard&lt;/h3&gt;&lt;/li&gt;
		&lt;li&gt;&lt;img src="images/7.jpg" /&gt;&lt;h3&gt;Smooth&lt;/h3&gt;&lt;/li&gt;
		&lt;li&gt;&lt;img src="images/8.jpg" /&gt;&lt;h3&gt;Rough&lt;/h3&gt;&lt;/li&gt;
	&lt;/ul&gt;
&lt;/div&gt;
</pre>
<p>And we transform it into the following:</p>
<pre class="brush:html">
&lt;div id="fc-slideshow" class="fc-slideshow"&gt;

	&lt;ul class="fc-slides"&gt;
		&lt;!-- ... --&gt;
	&lt;/ul&gt;

	&lt;nav&gt;
		&lt;div class="fc-left"&gt;
			&lt;span&gt;&lt;/span&gt;
			&lt;span&gt;&lt;/span&gt;
			&lt;span&gt;&lt;/span&gt;
			&lt;i class="icon-arrow-left"&gt;&lt;/i&gt;
		&lt;/div&gt;
		&lt;div class="fc-right"&gt;
			&lt;span&gt;&lt;/span&gt;
			&lt;span&gt;&lt;/span&gt;
			&lt;span&gt;&lt;/span&gt;
			&lt;i class="icon-arrow-right"&gt;&lt;/i&gt;
		&lt;/div&gt;
	&lt;/nav&gt;

	&lt;div class="fc-flip"&gt;
		&lt;div class="fc-front"&gt;
			&lt;div&gt;&lt;img src="images/4.jpg"&gt;&lt;h3&gt;Dark&lt;/h3&gt;&lt;/div&gt;
			&lt;div class="fc-overlay-light"&gt;&lt;/div&gt;
		&lt;/div&gt;
		&lt;div class="fc-back"&gt;
			&lt;div&gt;&lt;img src="images/5.jpg"&gt;&lt;h3&gt;Soft&lt;/h3&gt;&lt;/div&gt;
			&lt;div class="fc-overlay-dark"&gt;&lt;/div&gt;
		&lt;/div&gt;
	&lt;/div&gt;
	
&lt;/div&gt;
</pre>
<div class="ct-ad-article-wrapper ct-ad-article-wrapper-in"><div class="ct-ad-article"><img class="ct-ad-img" src="http://codropspz.tympanus.netdna-cdn.com/codrops/wp-content/themes/codropstheme02/images/advertisement.jpg" /><div id="bsap_1279993" class="bsarocks bsap_af25dfd2f1908889af7a1aa5f4dcbd9e"></div><div style="clear:both;"></div></div></div>
<p>The nav element has some empty spans that serve as &#8220;detection areas&#8221;. Each side of the circle has three areas that will be clickable, one at the top, one in the middle and one at the bottom. The i element will serve as a navigation arrow and depending on which span we are hovering, we will rotate the little arrow box to the right place. But we won&#8217;t use the arrow as the clickable area but the whole span.</p>
<p>The division for the circle flip contains a special 3D structure: it has a front and a back side. Once we navigate to the next or previous item, we will show that structure and rotate the flip container so that we see the back side.</p>
<p>The overlays make everything look a bit more realistic by providing light or darkness. We animate the opacity depending on the angle of rotation. </p>
<p>We simply call the plugin like this:</p>
<pre class="brush:js">
$( '#fc-slideshow' ).flipshow();
</pre>
<p>And this are the options for the plugin: </p>
<pre class="brush:js">
// the options
$.Flipshow.defaults = {
	// default transition speed (ms)
	speed : 700,
	// default transition easing
	easing : 'cubic-bezier(.29,1.44,.86,1.06)'
};
</pre>
<p>Please note, that this is very experimental and will only work as intended in browsers that support CSS 3d transforms. For others there is a simple fallback that simply shows and hides the previous or next item.</p>
<p>We hope you find this little plugin inspiring!</p>
<p><a class="demo" href="http://tympanus.net/Development/CircleFlipSlideshow/">View demo</a> <a class="download" href="http://tympanus.net/Development/CircleFlipSlideshow/CircleFlipSlideshow.zip">Download source</a></p>
]]></content:encoded>
			<wfw:commentRss>http://tympanus.net/codrops/2013/01/28/flipping-circle-slideshow/feed/</wfw:commentRss>
		<slash:comments>48</slash:comments>
		</item>
		<item>
		<title>3D Image Gallery Room</title>
		<link>http://tympanus.net/codrops/2013/01/15/3d-image-gallery-room/</link>
		<comments>http://tympanus.net/codrops/2013/01/15/3d-image-gallery-room/#comments</comments>
		<pubDate>Tue, 15 Jan 2013 13:48:52 +0000</pubDate>
		<dc:creator>Mary Lou</dc:creator>
				<category><![CDATA[Playground]]></category>
		<category><![CDATA[3d]]></category>
		<category><![CDATA[CSS3]]></category>
		<category><![CDATA[image gallery]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[transform]]></category>

		<guid isPermaLink="false">http://tympanus.net/codrops/?p=13564</guid>
		<description><![CDATA[An experimental image gallery with a realistic touch: the images are displayed in a 3D room with walls.]]></description>
				<content:encoded><![CDATA[<p><a href="http://tympanus.net/Development/3DGalleryRoom/"><img src="http://codropspz.tympanus.netdna-cdn.com/codrops/wp-content/uploads/2013/01/3DGalleryRoom.jpg" alt="3D Gallery Room" width="580" height="315" class="alignnone size-full wp-image-13595" /></a></p>
<p><a class="demo" href="http://tympanus.net/Development/3DGalleryRoom/">View demo</a> <a class="download" href="http://tympanus.net/Development/3DGalleryRoom/3DGalleryRoom.zip">Download source</a></p>
<p>Today we want to share another 3D experiment with you: a gallery room in 3D. The idea is to create a realistic environment for an image exposition using CSS 3D transforms. Images are &#8220;hanged&#8221; along a wall which will have an end. Once the end of the wall is reached, a rotation will happen and we&#8217;ll be turned to the next wall whith more images. To give a real sensation of being in a room, we only have four walls and corners. Each image will have a little description tag with a small-sized font and when clicking on it, a larger version will appear from below.</p>
<p><strong>Please note that this is highly experimental and probably very buggy.</strong></p>
<p>We recommend to view the demos in Google Chrome, they perform best there.</p>
<p>We use the following initial structure for adding figures and their captions:</p>
<pre class="brush:html">
&lt;div id="gr-gallery" class="gr-gallery"&gt;

	&lt;div class="gr-main"&gt;

		&lt;figure&gt;
			&lt;div&gt;&lt;img src="images/11.jpg" alt="img01" /&gt;&lt;/div&gt;
			&lt;figcaption&gt;
				&lt;h2&gt;&lt;span&gt;Penn. Station, Madison Square Garden and Empire State Building&lt;/span&gt;&lt;/h2&gt;
				&lt;div&gt;&lt;p&gt;New York City, 2009, by &lt;a href="http://www.flickr.com/photos/thomasclaveirole"&gt;Thomas Claveirole&lt;/a&gt;&lt;/p&gt;&lt;/div&gt;
			&lt;/figcaption&gt;
		&lt;/figure&gt;

		&lt;figure&gt;
			&lt;!-- --&gt;
		&lt;/figure&gt;

		&lt;!-- --&gt;
	&lt;/div&gt;
	
&lt;/div&gt;
</pre>
<p>We will first transform it into the following structure that will contain a &#8220;room&#8221; with a main &#8220;wall&#8221;:</p>
<pre class="brush:html">
&lt;div id="gr-gallery" class="gr-gallery"&gt;

	&lt;div class="gr-main" style="display: none;"&gt;
		&lt;!-- --&gt;
	&lt;/div&gt;

	&lt;div class="gr-room"&gt;
		&lt;div class="gr-wall-main"&gt;
			&lt;div class="gr-floor" style="width: 3382px;"&gt;&lt;/div&gt;
			&lt;figure&gt;&lt;/figure&gt;
			&lt;figure&gt;&lt;/figure&gt;
			&lt;!-- --&gt;
		&lt;/div&gt;
	&lt;/div&gt;

	&lt;nav&gt;
		&lt;span class="gr-prev"&gt;prev&lt;/span&gt;
		&lt;span class="gr-next"&gt;next&lt;/span&gt;
	&lt;/nav&gt;

	&lt;div class="gr-caption"&gt;
		&lt;span class="gr-caption-close"&gt;x&lt;/span&gt;
	&lt;/div&gt;
	
&lt;/div&gt;&lt;!-- /gr-gallery --&gt;
</pre>
<p>The main wall will get a width so that a certain amount of images fits inside. The default number of images per wall are the total number divided by four since we have four walls to spread them on. We can also set the number of items per wall by initializing the layout array, as see in the demos:</p>
<pre class="brush:js">
Gallery.init( {
	layout : [3,2,3,2]
} );
</pre>
<p>Now, when we reach the end of a wall and rotate to see the next one, we&#8217;ll add another wall dynamically and set the right transforms so that it&#8217;s in the right angle towards the main wall. </p>
<div class="ct-ad-article-wrapper ct-ad-article-wrapper-in"><div class="ct-ad-article"><img class="ct-ad-img" src="http://codropspz.tympanus.netdna-cdn.com/codrops/wp-content/themes/codropstheme02/images/advertisement.jpg" /><div id="bsap_1279993" class="bsarocks bsap_af25dfd2f1908889af7a1aa5f4dcbd9e"></div><div style="clear:both;"></div></div></div>
<p>Let&#8217;s take a look at some screenshots. The gallery starts by looking at the first image which will be centered in the viewport. With a very large screen, we will be able to see the neighboring images as well, depending on the wall size of course:</p>
<p><img src="http://codropspz.tympanus.netdna-cdn.com/codrops/wp-content/uploads/2013/01/3DGalleryRoom_01.jpg" alt="3DGalleryRoom_01" width="580" height="525" class="alignnone size-full wp-image-13588" /></p>
<p>When clicking on the little description, a larger version will slide in from the bottom of the screen:<br />
<img src="http://codropspz.tympanus.netdna-cdn.com/codrops/wp-content/uploads/2013/01/3DGalleryRoom_02.jpg" alt="3DGalleryRoom_02" width="580" height="525" class="alignnone size-full wp-image-13589" /></p>
<p>When clicking on a navigation arrow (we click to go to the right) we will move to the next or previous picture. When the end of the wall is reached, we&#8217;ll give a turn:<br />
<img src="http://codropspz.tympanus.netdna-cdn.com/codrops/wp-content/uploads/2013/01/3DGalleryRoom_03.jpg" alt="3DGalleryRoom_03" width="580" height="525" class="alignnone size-full wp-image-13590" /></p>
<p>The next image is placed into another wall a positioned accordingly:<br />
<img src="http://codropspz.tympanus.netdna-cdn.com/codrops/wp-content/uploads/2013/01/3DGalleryRoom_04.jpg" alt="3DGalleryRoom_04" width="580" height="525" class="alignnone size-full wp-image-13591" /></p>
<p>When we turn fully, the walls will be reset and we&#8217;ll again have only the main wall:<br />
<img src="http://codropspz.tympanus.netdna-cdn.com/codrops/wp-content/uploads/2013/01/3DGalleryRoom_05.jpg" alt="3DGalleryRoom_05" width="580" height="524" class="alignnone size-full wp-image-13592" /></p>
<p>The biggest problem for these kind of extreme experiments is the different handling of 3D transforms in the browsers and of course the performance. When playing with extreme widths and perspective, there can be glitches in viewing because an element might be rotated &#8220;right into your face&#8221; :) The larger the element is in width, the higher the perspective value needs to be (at least for Firefox).</p>
<p>Sadly, the performance suffers when adding something like a box shadow, so we have stripped the demos down to their bare style and not added too much fanciness. It does look a bit ugly, but we simply wanted to show the 3D effect and the smoothness is more important for us in this experiment. </p>
<p><em>Anyway, we hope you enjoyed this little experiment and find it inspiring!</em></p>
<p><a class="demo" href="http://tympanus.net/Development/3DGalleryRoom/">View demo</a> <a class="download" href="http://tympanus.net/Development/3DGalleryRoom/3DGalleryRoom.zip">Download source</a></p>
]]></content:encoded>
			<wfw:commentRss>http://tympanus.net/codrops/2013/01/15/3d-image-gallery-room/feed/</wfw:commentRss>
		<slash:comments>33</slash:comments>
		</item>
		<item>
		<title>3D Book Showcase</title>
		<link>http://tympanus.net/codrops/2013/01/08/3d-book-showcase/</link>
		<comments>http://tympanus.net/codrops/2013/01/08/3d-book-showcase/#comments</comments>
		<pubDate>Tue, 08 Jan 2013 15:37:31 +0000</pubDate>
		<dc:creator>Mary Lou</dc:creator>
				<category><![CDATA[Playground]]></category>
		<category><![CDATA[3d]]></category>
		<category><![CDATA[book]]></category>
		<category><![CDATA[CSS3]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[transform]]></category>

		<guid isPermaLink="false">http://tympanus.net/codrops/?p=13406</guid>
		<description><![CDATA[An experiment about a realistic looking book showcase with some interactivity using CSS 3D transforms.]]></description>
				<content:encoded><![CDATA[<p><a href="http://tympanus.net/Development/3DBookShowcase/"><img src="http://codropspz.tympanus.netdna-cdn.com/codrops/wp-content/uploads/2013/01/3DBookShowcase_Main.jpg" alt="3DBookShowcase_Main" width="580" height="315" class="alignnone size-full wp-image-13409" /></a></p>
<p><a class="demo" href="http://tympanus.net/Development/3DBookShowcase/">View demo</a> <a class="download" href="http://tympanus.net/Development/3DBookShowcase/3DBookShowcase.zip">Download source</a></p>
<p>Today we want to share an experimental book showcase concept with you. The idea is to make books look more realistic by using 3D transforms and apply some fun effects to them, like rotating, flipping and opening. This might be an interesting concept for online book stores as it adds some interactivity the user might find entertaining. The idea is taken from <a href="http://www.liftinteractive.com/">Lift Interactive</a> (scroll down to see the book style).</p>
<p><strong>Note that this only works in browsers that support CSS 3D transforms. For other browsers, we simply show the book cover.</strong></p>
<p><em>The demos are best viewed in WebKit browsers.</em></p>
<p><img src="http://codropspz.tympanus.netdna-cdn.com/codrops/wp-content/uploads/2013/01/3DBookShowcase.jpg" alt="3DBookShowcase" width="580" height="406" class="alignnone size-full wp-image-13413" /></p>
<p>What we did was to build a structure that we can transform into a 3D object with CSS 3D transforms. Our book has six main sides and one inner page element that we&#8217;ll use to paginate through some content, simulating something like a &#8220;view inside&#8221; functionality. We could have used the <a href="http://tympanus.net/codrops/2012/09/03/bookblock-a-content-flip-plugin/">BookBlock jQuery plugin</a> for flipping through the pages but we didn&#8217;t want to overload it with too many effects. </p>
<p>A book is build up as follows:</p>
<pre class="brush:html">
&lt;div class="bk-book"&gt;

	&lt;div class="bk-front"&gt;
		&lt;div class="bk-cover"&gt;
			&lt;h2&gt;
				&lt;span&gt;Anthony Burghiss&lt;/span&gt;
				&lt;span&gt;A Catwork Orange&lt;/span&gt;
			&lt;/h2&gt;
		&lt;/div&gt;
		&lt;div class="bk-cover-back"&gt;&lt;/div&gt;
	&lt;/div&gt;

	&lt;div class="bk-page"&gt;
		&lt;div class="bk-content bk-content-current"&gt;
			&lt;p&gt;Red snapper Kafue pike fangtooth humums slipmouth, salmon cutlassfish; swallower European perch mola mola sunfish, threadfin bream. Billfish hog sucker trout-perch lenok orbicular velvetfish. Delta smelt striped bass, medusafish dragon goby starry flounder cuchia round whitefish northern anchovy spadefish merluccid hake cat shark Black pickerel. Pacific cod.&lt;/p&gt;
		&lt;/div&gt;
		&lt;div class="bk-content"&gt;
			&lt;!-- ... --&gt;
		&lt;/div&gt;
		&lt;div class="bk-content"&gt;
			&lt;!-- ... --&gt;
		&lt;/div&gt;
	&lt;/div&gt;

	&lt;div class="bk-back"&gt;
		&lt;p&gt;In this nightmare vision of cats in revolt, fifteen-year-old Alex and his friends set out on a diabolical orgy of robbery, rape, torture and murder. Alex is jailed for his teenage delinquency and the State tries to reform him - but at what cost?&lt;/p&gt;
	&lt;/div&gt;

	&lt;div class="bk-right"&gt;&lt;/div&gt;

	&lt;div class="bk-left"&gt;
		&lt;h2&gt;
			&lt;span&gt;Anthony Burghiss&lt;/span&gt;
			&lt;span&gt;A Catwork Orange&lt;/span&gt;
		&lt;/h2&gt;
	&lt;/div&gt;

	&lt;div class="bk-top"&gt;&lt;/div&gt;

	&lt;div class="bk-bottom"&gt;&lt;/div&gt;
&lt;/div&gt;
</pre>
<p>The class names are based on the sides of a book when holding it and looking at the front, the cover. Since we want to open the book cover, we need to give the front a main cover side and a back side. The back of the book will also contain some content which will be visible when flipping the book. </p>
<p>When hovering over a book, we will rotate it slightly.</p>
<p><img src="http://codropspz.tympanus.netdna-cdn.com/codrops/wp-content/uploads/2013/01/3DBookShowcase2.jpg" alt="3DBookShowcase2" width="580" height="277" class="alignnone size-full wp-image-13412" /></p>
<p>Specifically, we rotate the whole book 35 degrees on the Y-axis:</p>
<pre class="brush:css">
.bk-list li .bk-book.bk-bookdefault:hover {
	transform: rotate3d(0,1,0,35deg);
}
</pre>
<div class="ct-ad-article-wrapper ct-ad-article-wrapper-in"><div class="ct-ad-article"><img class="ct-ad-img" src="http://codropspz.tympanus.netdna-cdn.com/codrops/wp-content/themes/codropstheme02/images/advertisement.jpg" /><div id="bsap_1279993" class="bsarocks bsap_af25dfd2f1908889af7a1aa5f4dcbd9e"></div><div style="clear:both;"></div></div></div>
<p>When opening the book by clicking on &#8220;View inside&#8221;, the front part will flip open and we can navigate through the preview pages by clicking on the arrows.</p>
<p><img src="http://codropspz.tympanus.netdna-cdn.com/codrops/wp-content/uploads/2013/01/3DBookShowcase3.jpg" alt="3DBookShowcase3" width="580" height="404" class="alignnone size-full wp-image-13411" /></p>
<p>The rotations and flipping are done by applying certain classes: </p>
<pre class="brush:css">
/* Transform classes */

.bk-list li .bk-viewinside .bk-front {
	transform: translate3d(0,0,20px) rotate3d(0,1,0,-160deg);
}

.bk-list li .bk-book.bk-viewinside {
	transform: translate3d(0,0,150px) rotate3d(0,1,0,0deg);
}

.bk-list li .bk-book.bk-viewback {
	transform: translate3d(0,0,0px) rotate3d(0,1,0,180deg);
}
</pre>
<p>In the second demo, we rotate the book so that we can only see the spine, the left side. On hover we simulate the familiar movement of taking a quick look of a book by slightly moving it towards us and rotating it. When clicking on it we will open it.</p>
<p><img src="http://codropspz.tympanus.netdna-cdn.com/codrops/wp-content/uploads/2013/01/3DBookShowcase4.jpg" alt="3DBookShowcase4" width="580" height="314" class="alignnone size-full wp-image-13410" /></p>
<p>A second click on the book will close it again and put it back into the shelf.</p>
<p>Note that this is really just a concept and highly experimental. It&#8217;s probably very buggy and has much room for improvement. But anyway, we hope you enjoyed this experiment and find it inspiring!</p>
<p><a class="demo" href="http://tympanus.net/Development/3DBookShowcase/">View demo</a> <a class="download" href="http://tympanus.net/Development/3DBookShowcase/3DBookShowcase.zip">Download source</a></p>
]]></content:encoded>
			<wfw:commentRss>http://tympanus.net/codrops/2013/01/08/3d-book-showcase/feed/</wfw:commentRss>
		<slash:comments>49</slash:comments>
		</item>
		<item>
		<title>How to Create a Simple Multi-Item Slider</title>
		<link>http://tympanus.net/codrops/2012/12/31/how-to-create-a-simple-multi-item-slider/</link>
		<comments>http://tympanus.net/codrops/2012/12/31/how-to-create-a-simple-multi-item-slider/#comments</comments>
		<pubDate>Mon, 31 Dec 2012 12:19:33 +0000</pubDate>
		<dc:creator>Mary Lou</dc:creator>
				<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[animation]]></category>
		<category><![CDATA[CSS3]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[minimalistic]]></category>

		<guid isPermaLink="false">http://tympanus.net/codrops/?p=13218</guid>
		<description><![CDATA[A tutorial on how to create a simple category slider with a minimal design using CSS animations and jQuery. The idea is to slide the items sequentially depending on the slide direction.]]></description>
				<content:encoded><![CDATA[<p><a href="http://tympanus.net/Tutorials/ItemSlider/"><img src="http://codropspz.tympanus.netdna-cdn.com/codrops/wp-content/uploads/2012/12/SimpleMultiItemSlider.jpg" alt="How to Create a Simple Multi-Item Slider" width="580" height="315" class="alignnone size-full wp-image-13226" /></a></p>
<p><a class="demo" href="http://tympanus.net/Tutorials/ItemSlider/">View demo</a> <a class="download" href="http://tympanus.net/Tutorials/ItemSlider/ItemSlider.zip">Download source</a></p>
<p>For today&#8217;s tutorial we want to show you how to create a simple item slider with CSS animations and some jQuery. The idea was inspired by the Aplle product slider where several little items fly in with a bouncing animation. We wanted to translate this concept to a modern-looking alternative for a <a href="http://tympanus.net/codrops/2012/12/26/tips-for-a-clean-and-minimal-online-store-design/">minimal online store design</a> where the items represent different categories. Categories as use-case fit quite well because of the limited nature of this type of slider. For more items to be shown, this is certainly a far-from-optimal solution. If the amount of items is limited this might give an interesting little touch to the experience.</p>
<p><strong>So, let&#8217;s get started with this last tutorial of 2012!</strong></p>
<h3>The Markup</h3>
<p>For the HTML we will use a division that wraps some unordered lists that will contain the items and a navigation with the category links. Each list item will have a link that contains an image and a h4 heading.</p>
<pre class="brush:html">
&lt;div id="mi-slider" class="mi-slider"&gt;
	&lt;ul&gt;
		&lt;li&gt;&lt;a href="#"&gt;&lt;img src="images/1.jpg" alt="img01"&gt;&lt;h4&gt;Boots&lt;/h4&gt;&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;&lt;a href="#"&gt;&lt;img src="images/2.jpg" alt="img02"&gt;&lt;h4&gt;Oxfords&lt;/h4&gt;&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;&lt;a href="#"&gt;&lt;img src="images/3.jpg" alt="img03"&gt;&lt;h4&gt;Loafers&lt;/h4&gt;&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;&lt;a href="#"&gt;&lt;img src="images/4.jpg" alt="img04"&gt;&lt;h4&gt;Sneakers&lt;/h4&gt;&lt;/a&gt;&lt;/li&gt;
	&lt;/ul&gt;
	&lt;ul&gt;
		&lt;li&gt;&lt;a href="#"&gt;&lt;img src="images/5.jpg" alt="img05"&gt;&lt;h4&gt;Belts&lt;/h4&gt;&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;&lt;a href="#"&gt;&lt;img src="images/6.jpg" alt="img06"&gt;&lt;h4&gt;Hats &amp; Caps&lt;/h4&gt;&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;&lt;a href="#"&gt;&lt;img src="images/7.jpg" alt="img07"&gt;&lt;h4&gt;Sunglasses&lt;/h4&gt;&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;&lt;a href="#"&gt;&lt;img src="images/8.jpg" alt="img08"&gt;&lt;h4&gt;Scarves&lt;/h4&gt;&lt;/a&gt;&lt;/li&gt;
	&lt;/ul&gt;
	&lt;ul&gt;
		&lt;li&gt;&lt;a href="#"&gt;&lt;img src="images/9.jpg" alt="img09"&gt;&lt;h4&gt;Casual&lt;/h4&gt;&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;&lt;a href="#"&gt;&lt;img src="images/10.jpg" alt="img10"&gt;&lt;h4&gt;Luxury&lt;/h4&gt;&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;&lt;a href="#"&gt;&lt;img src="images/11.jpg" alt="img11"&gt;&lt;h4&gt;Sport&lt;/h4&gt;&lt;/a&gt;&lt;/li&gt;
	&lt;/ul&gt;
	&lt;ul&gt;
		&lt;li&gt;&lt;a href="#"&gt;&lt;img src="images/12.jpg" alt="img12"&gt;&lt;h4&gt;Carry-Ons&lt;/h4&gt;&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;&lt;a href="#"&gt;&lt;img src="images/13.jpg" alt="img13"&gt;&lt;h4&gt;Duffel Bags&lt;/h4&gt;&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;&lt;a href="#"&gt;&lt;img src="images/14.jpg" alt="img14"&gt;&lt;h4&gt;Laptop Bags&lt;/h4&gt;&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;&lt;a href="#"&gt;&lt;img src="images/15.jpg" alt="img15"&gt;&lt;h4&gt;Briefcases&lt;/h4&gt;&lt;/a&gt;&lt;/li&gt;
	&lt;/ul&gt;
	&lt;nav&gt;
		&lt;a href="#"&gt;Shoes&lt;/a&gt;
		&lt;a href="#"&gt;Accessories&lt;/a&gt;
		&lt;a href="#"&gt;Watches&lt;/a&gt;
		&lt;a href="#"&gt;Bags&lt;/a&gt;
	&lt;/nav&gt;
&lt;/div&gt;
</pre>
<p>Let&#8217;s take a look at the style.</p>
<h3>The CSS</h3>
<p><em>Note that the CSS will not contain any vendor prefixes, but you will find them in the files.</em><br />
What we want to do is the following: initially we just want the first item list to show while all the other <code>li</code>s will be translated to the right, outside of the viewport. When we click on a navigation link the items will either slide in from the right or from the left, depending on which current position we are at and what the newly selected category is. </p>
<p>Let&#8217;s first style the wrapper, which is the division with the class <strong>mi-slider</strong>. It will have a predefined height which we need in order to set the position of the <code>ul</code>s correctly:</p>
<pre class="brush:css">
.mi-slider {
	position: relative;
	margin-top: 30px;
	height: 490px;
}
</pre>
<p>The <code>ul</code> will be positioned absolutely which means that all the lists will be on top of each other. Remember, we only want to translate the list items, not the lists themselves. We set the pointer-events to none because we want to be able to click on the current list&#8217;s links:</p>
<pre class="brush:css">
.mi-slider ul {
	list-style-type: none;
	position: absolute;
	width: 100%;
	left: 0;
	bottom: 140px;
	overflow: hidden;
	text-align: center;
	pointer-events: none;
}
</pre>
<p>The pointer events of the current list should be reset, so that the containing links are clickable:</p>
<pre class="brush:css">
.mi-slider ul.mi-current {
	pointer-events: auto;
}
</pre>
<p>When JavaScript is disabled, we don&#8217;t want anything to look broken (we use Modernizr):</p>
<pre class="brush:css">
.no-js .mi-slider ul {
	position: relative;
	left: auto;
	bottom: auto;
	margin: 0;
	overflow: visible;
}
</pre>
<p>In order to center all the list items, we have given the <code>ul</code> a text-align of center and now we&#8217;ll give the list items an inline-block display with a width of 20%. This width makes sure that our items fit into the list and keeps it fluid.<br />
By default, all the list items will be translated to the right. We use 600% here because it&#8217;s a large enought value to move them out of the viewport. We&#8217;ll also add a little transition for the opacity:</p>
<pre class="brush:css">
.mi-slider ul li {
	display: inline-block;
	padding: 20px;
	width: 20%;
	max-width: 300px;
	transform: translateX(600%);
	transition: opacity 0.2s linear;
}
</pre>
<p>Whithout JS we don&#8217;t want them to translate:</p>
<pre class="brush:css">
.no-js .mi-slider ul li {
	transform: translateX(0);
}
</pre>
<div class="ct-ad-article-wrapper ct-ad-article-wrapper-in"><div class="ct-ad-article"><img class="ct-ad-img" src="http://codropspz.tympanus.netdna-cdn.com/codrops/wp-content/themes/codropstheme02/images/advertisement.jpg" /><div id="bsap_1279993" class="bsarocks bsap_af25dfd2f1908889af7a1aa5f4dcbd9e"></div><div style="clear:both;"></div></div></div>
<p>Let&#8217;s style the content of the list items. Note how we set the max-width of the images to 100%. This will ensure that the layout does not break but the images will resize according to their wrapper which is our <code>li</code> with a percentage-based width:</p>
<pre class="brush:css">
.mi-slider ul li a,
.mi-slider ul li img {
	display: block;
	margin: 0 auto;
}

.mi-slider ul li a {
	outline: none;
	cursor: pointer;
}

.mi-slider ul li img {
	max-width: 100%;
	border: none;
}

.mi-slider ul li h4 {
	display: inline-block;
	font-family: Baskerville, "Baskerville Old Face", "Hoefler Text", Garamond, "Times New Roman", serif;
	font-style: italic;
	font-weight: 400;
	font-size: 18px;
	padding: 20px 10px 0;
}
</pre>
<p>On hover, we&#8217;ll animate the opacity of the list item:</p>
<pre class="brush:css">
.mi-slider ul li:hover {
	opacity: 0.7;
} 
</pre>
<p>The navigation needs to have a top value because the lists are positioned absolutely. We&#8217;ll center the navigation by giving lateral auto margins and we&#8217;ll set a maximum width of 800px:</p>
<pre class="brush:css">
.mi-slider nav {
	position: relative;
	top: 400px;
	text-align: center;
	max-width: 800px;
	margin: 0 auto;
	border-top: 5px solid #333;
}
</pre>
<p>We don&#8217;t want to show the navigation at all when there is no JavaScript enabled:</p>
<pre class="brush:css">
.no-js nav {
	display: none;
}
</pre>
<p>The navigation links will have a generous padding and we&#8217;ll give them a transition for hover:</p>
<pre class="brush:css">
.mi-slider nav a {
	display: inline-block;
	text-transform: uppercase;
	letter-spacing: 5px;
	padding: 40px 30px 30px 34px;
	position: relative;
	color: #888;
	outline: none;
	transition: color 0.2s linear;
}

.mi-slider nav a:hover,
.mi-slider nav a.mi-selected {
	color: #000;
}

</pre>
<p>The <strong>mi-selected</strong> class, just like the <strong>mi-current</strong> class for the lists, we&#8217;ll set using JavaScript.</p>
<p>Now, let&#8217;s add that little arrow on the top. We&#8217;ll use the pseudo-classes :before and :after to create two triangles with borders: </p>
<pre class="brush:css">
.mi-slider nav a.mi-selected:after,
.mi-slider nav a.mi-selected:before {
	content: '';
	position: absolute;
	top: -5px;
	border: solid transparent;
	height: 0;
	width: 0;
	position: absolute;
	pointer-events: none;
}

.mi-slider nav a.mi-selected:after {
	border-color: transparent;
	border-top-color: #fff;
	border-width: 20px;
	left: 50%;
	margin-left: -20px;
}

.mi-slider nav a.mi-selected:before {
	border-color: transparent;
	border-top-color: #333;
	border-width: 27px;
	left: 50%;
	margin-left: -27px;
}
</pre>
<p>Let get to the juicy bits, the animations. The first animation that we want to happen, is the scaling up of the items of the first list. The <strong>scaleUp</strong> animation will also include the items being translated to 0 because we want them to be in the viewport:</p>
<pre class="brush:css">
.mi-slider ul:first-child li,
.no-js .mi-slider ul li {
	animation: scaleUp 350ms ease-in-out both;
}

@keyframes scaleUp {
	0% { transform: translateX(0) scale(0); }
	100% { transform: translateX(0) scale(1); }
}
</pre>
<p>Let&#8217;s add a different delay to each list item so that they appear sequentially:</p>
<pre class="brush:css">
.mi-slider ul:first-child li:first-child {
	animation-delay: 90ms;
}

.mi-slider ul:first-child li:nth-child(2) {
	animation-delay: 180ms;
}

.mi-slider ul:first-child li:nth-child(3) {
	animation-delay: 270ms;
}

.mi-slider ul:first-child li:nth-child(4) {
	animation-delay: 360ms;
}
</pre>
<p>For our example we will just have a maximum of four items, so we&#8217;ll only define four delays. If we would have more items, we would include more delays.</p>
<p>For the sliding animations we will have four cases: two for the sliding in of new items and two for the sliding out of the current items, depending on the direction. So we&#8217;ll define four classes for the lists which we will add with JavaScript:</p>
<pre class="brush:css">
/* moveFromRight */

.mi-slider ul.mi-moveFromRight li {
	animation: moveFromRight 350ms ease-in-out both;
}

/* moveFromLeft */

.mi-slider ul.mi-moveFromLeft li {
	animation: moveFromLeft 350ms ease-in-out both;
}

/* moveToRight */

.mi-slider ul.mi-moveToRight li {
	animation: moveToRight 350ms ease-in-out both;
}

/* moveToLeft */

.mi-slider ul.mi-moveToLeft li {
	animation: moveToLeft 350ms ease-in-out both;
}
</pre>
<p>Now we need to set the according animation delays which will also depend on the direction. For example, the first item will slide in with no delay if it&#8217;s coming form the right side and also when it slides out to the left. The same will be true for the last item:</p>
<pre class="brush:css">
.mi-slider ul.mi-moveToLeft li:first-child,
.mi-slider ul.mi-moveFromRight li:first-child,
.mi-slider ul.mi-moveToRight li:nth-child(4),
.mi-slider ul.mi-moveFromLeft li:nth-child(4) {
	animation-delay: 0ms;
}
</pre>
<p>The increased delays will be set accordingly:</p>
<pre class="brush:css">
.mi-slider ul.mi-moveToLeft li:nth-child(2),
.mi-slider ul.mi-moveFromRight li:nth-child(2),
.mi-slider ul.mi-moveToRight li:nth-child(3),
.mi-slider ul.mi-moveFromLeft li:nth-child(3) {
	-webkit-animation-delay: 90ms;
	animation-delay: 90ms;
}

.mi-slider ul.mi-moveToLeft li:nth-child(3),
.mi-slider ul.mi-moveFromRight li:nth-child(3),
.mi-slider ul.mi-moveToRight li:nth-child(2),
.mi-slider ul.mi-moveFromLeft li:nth-child(2) {
	-webkit-animation-delay: 180ms;
	animation-delay: 180ms;
}

.mi-slider ul.mi-moveToLeft li:nth-child(4),
.mi-slider ul.mi-moveFromRight li:nth-child(4),
.mi-slider ul.mi-moveToRight li:first-child,
.mi-slider ul.mi-moveFromLeft li:first-child  {
	-webkit-animation-delay: 270ms;
	animation-delay: 270ms;
}
</pre>
<p>And now let&#8217;s define the animations itself. For example, moving from the right will mean that we will set the translateX value to 600% and move to 0. Moving from the left, we&#8217;ll set the initial position to -600% so that the items are on the left side outside of the viewport. And so on:</p>
<pre class="brush:css">
@keyframes moveFromRight {
	0% { transform: translateX(600%); }
	100% { transform: translateX(0); }
}

@keyframes moveFromLeft {
	0% { transform: translateX(-600%); }
	100% { transform: translateX(0); }
}

@keyframes moveToRight {
	0% { transform: translateX(0%); }
	100% { transform: translateX(600%); }
}

@keyframes moveToLeft {
	0% { transform: translateX(0%); }
	100% { transform: translateX(-600%); }
}
</pre>
<p>Last, but not least, let&#8217;s use some media queries to adjust the slider content for smaller screens.</p>
<p>We&#8217;ll start with adjusting the navigation so that it does not break when the screen is too small:</p>
<pre class="brush:css">

@media screen and (max-width: 910px){
	.mi-slider nav {
		max-width: 90%;
	}

	.mi-slider nav a {
		font-size: 12px;
		padding: 40px 10px 30px 14px;
	}
}
</pre>
<p>Since we set a fixed height to the slider, we want to make sure it adapts:</p>
<pre class="brush:css">
@media screen and (max-width: 740px){
	.mi-slider {
		height: 300px;
	}

	.mi-slider nav {
		top: 220px;
	}
}
</pre>
<p>For really small screens, we don&#8217;t simply want to make everything super tiny, but instead we want to make the navigation easy for touch devices. So we&#8217;ll simply show all the categories. We&#8217;ll set all the styles in a way that nothing is hidden and all the lists are displayed under each other:</p>
<pre class="brush:css">
@media screen and (max-width: 490px){ 
	.mi-slider {
		text-align: center;
		height: auto;
	}

	.mi-slider ul {
		position: relative;
		display: inline;
		bottom: auto;
		pointer-events: auto;
	}

	.mi-slider ul li {
		animation: none !important;
		transform: translateX(0) !important;
		padding: 10px 3px;
		min-width: 140px;
	}

	.mi-slider nav {
		display: none;
	}
}
</pre>
<p>And that&#8217;s all the style. Now let&#8217;s control some things with jQuery.</p>
<h3>The JavaScript</h3>
<p>Let&#8217;s create a simple jQuery plugin for our slider. Most of the work is done in the CSS where we have defined all the animations. The plugin will mainly focus on adding and removing classes and control the current category being shown. For browsers that don&#8217;t support animations we will fall back to a simple show/hide approach.</p>
<p>Let&#8217;s start by caching some elements and initialize some variables:</p>
<pre class="brush:js">
_init : function( options ) {

	// the categories (ul)
	this.$categories = this.$el.children( 'ul' );
	// the navigation
	this.$navcategories = this.$el.find( 'nav > a' );
	var animEndEventNames = {
		'WebkitAnimation' : 'webkitAnimationEnd',
		'OAnimation' : 'oAnimationEnd',
		'msAnimation' : 'MSAnimationEnd',
		'animation' : 'animationend'
	};
	// animation end event name
	this.animEndEventName = animEndEventNames[ Modernizr.prefixed( 'animation' ) ];
	// animations and transforms support
	this.support = Modernizr.csstransforms &#038;&#038; Modernizr.cssanimations;
	// if currently animating
	this.isAnimating = false;
	// current category
	this.current = 0;
	var $currcat = this.$categories.eq( 0 );
	if( !this.support ) {
		this.$categories.hide();
		$currcat.show();
	}
	else {
		$currcat.addClass( 'mi-current' );
	}
	// current nav category
	this.$navcategories.eq( 0 ).addClass( 'mi-selected' );
	// initialize the events
	this._initEvents();

}
</pre>
<p>We will bind the click event to the navigation category links under the slider. We assume that the index of each one corresponds to the index of the respective category (the <code>ul</code>). When a category link is clicked the items of the current category fly out, and the ones of the new category fly in one by one (remember, we defined the animation delays in the CSS).</p>
<pre class="brush:js">
_initEvents : function() {

	var self = this;
	this.$navcategories.on( 'click.catslider', function() {
		self.showCategory( $( this ).index() );
		return false;
	} );

	// reset on window resize..
	$( window ).on( 'resize', function() {
		self.$categories.removeClass().eq( 0 ).addClass( 'mi-current' );
		self.$navcategories.eq( self.current ).removeClass( 'mi-selected' ).end().eq( 0 ).addClass( 'mi-selected' );
		self.current = 0;
	} );

}

showCategory : function( catidx ) {

	if( catidx === this.current || this.isAnimating ) {
		return false;
	}
	this.isAnimating = true;
	// update selected navigation
	this.$navcategories.eq( this.current ).removeClass( 'mi-selected' ).end().eq( catidx ).addClass( 'mi-selected' );

	var dir = catidx > this.current ? 'right' : 'left',
		toClass = dir === 'right' ? 'mi-moveToLeft' : 'mi-moveToRight',
		fromClass = dir === 'right' ? 'mi-moveFromRight' : 'mi-moveFromLeft',
		// current category
		$currcat = this.$categories.eq( this.current ),
		// new category
		$newcat = this.$categories.eq( catidx ),
		$newcatchild = $newcat.children(),
		lastEnter = dir === 'right' ? $newcatchild.length - 1 : 0,
		self = this;

	if( this.support ) {

		$currcat.removeClass().addClass( toClass );
		
		setTimeout( function() {

			$newcat.removeClass().addClass( fromClass );
			$newcatchild.eq( lastEnter ).on( self.animEndEventName, function() {

				$( this ).off( self.animEndEventName );
				$newcat.addClass( 'mi-current' );
				self.current = catidx;
				var $this = $( this );
				// solve chrome bug
				self.forceRedraw( $this.get(0) );
				self.isAnimating = false;

			} );

		}, $newcatchild.length * 90 );

	}
	else {

		$currcat.hide();
		$newcat.show();
		this.current = catidx;
		this.isAnimating = false;

	}

}
</pre>
<p>And that&#8217;s it! I hope you enjoyed this tutorial and find it useful and inspiring!<br />
<strong>We wish you a happy new year!</strong> </p>
<div class="ct-github-link"><a href="https://github.com/codrops/ItemSlider">Find this project on Github</a></div>
<p><a class="demo" href="http://tympanus.net/Tutorials/ItemSlider/">View demo</a> <a class="download" href="http://tympanus.net/Tutorials/ItemSlider/ItemSlider.zip">Download source</a></p>
]]></content:encoded>
			<wfw:commentRss>http://tympanus.net/codrops/2012/12/31/how-to-create-a-simple-multi-item-slider/feed/</wfw:commentRss>
		<slash:comments>72</slash:comments>
		</item>
		<item>
		<title>Slider Pagination Concept</title>
		<link>http://tympanus.net/codrops/2012/12/21/slider-pagination-concept/</link>
		<comments>http://tympanus.net/codrops/2012/12/21/slider-pagination-concept/#comments</comments>
		<pubDate>Fri, 21 Dec 2012 14:47:32 +0000</pubDate>
		<dc:creator>Mary Lou</dc:creator>
				<category><![CDATA[Playground]]></category>
		<category><![CDATA[concept]]></category>
		<category><![CDATA[CSS3]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[Pagination]]></category>
		<category><![CDATA[slider]]></category>
		<category><![CDATA[ui]]></category>

		<guid isPermaLink="false">http://tympanus.net/codrops/?p=13079</guid>
		<description><![CDATA[An experimental slider pagination using the jQuery UI slider. The idea is to use a simple navigation concept that preserves layout and style while allowing content to stay easily accessible.]]></description>
				<content:encoded><![CDATA[<p><a href="http://tympanus.net/Development/SliderPagination/"><img src="http://codropspz.tympanus.netdna-cdn.com/codrops/wp-content/uploads/2012/12/SliderPagination.jpg" alt="Slider Pagination Concept" title="Slider Pagination Concept" width="580" height="315" class="alignnone size-full wp-image-13085" /></a></p>
<p><a class="demo" href="http://tympanus.net/Development/SliderPagination/">View demo</a> <a class="download" href="http://tympanus.net/Development/SliderPagination/SliderPagination.zip">Download source</a></p>
<p>A pagination is an essential part of any content-rich website, such as a magazine or a blog. The classic pagination will consist of linked numbers and some maybe some arrows, a presentation that has its limits. If you have a lot of pages to show, your pagination will either grow out of proportion breaking the design, or, if you don&#8217;t want to show all pages, you&#8217;ll need to add some kind of access point for the pages in between, requiring an additional user action. </p>
<p>Thinking about a way to navigate pages in a more compact and novel way, we tried our luck with the jQuery UI slider. The idea of using a slider for this came from this brilliant <a href="http://codepen.io/simurai/pen/Btnrc"><strong>Number Slider</strong></a> pen by simurai.</p>
<p>With a slider pagination we can reach any page quickly by just dragging the handle. Adding a set of arrows makes it easy to navigate to the previous or next page.</p>
<div class="ct-ad-article-wrapper ct-ad-article-wrapper-in"><div class="ct-ad-article"><img class="ct-ad-img" src="http://codropspz.tympanus.netdna-cdn.com/codrops/wp-content/themes/codropstheme02/images/advertisement.jpg" /><div id="bsap_1279993" class="bsarocks bsap_af25dfd2f1908889af7a1aa5f4dcbd9e"></div><div style="clear:both;"></div></div></div>
<p>The main idea is to initially just show a little button with two arrows. The button shows the current page number and clicking on the arrows will navigate to the next or previous page:</p>
<p><img src="http://codropspz.tympanus.netdna-cdn.com/codrops/wp-content/uploads/2012/12/SliderPagination01.jpg" alt="SliderPagination01" title="" width="600" height="452" class="alignnone size-full wp-image-13081" /></p>
<p>Clicking on the button will make the slider appear; the button handle will be animated to the correct part of the slider. Now we can drag the slider to the desired page. Once we release the handle to drop it, the slider will go back to the initial state, with the updated page number:</p>
<p><img src="http://codropspz.tympanus.netdna-cdn.com/codrops/wp-content/uploads/2012/12/SliderPagination02.jpg" alt="SliderPagination02" title="" width="600" height="452" class="alignnone size-full wp-image-13082" /></p>
<p>Using a slider of this kind will not break a layout when there are many pages to display. It does require an additional click, though. But it might as well be a bit more fun to navigate :)</p>
<p><strong>What do you think? Is is going into an interesting direction for navigating pages or do you prefer the classic way?</strong><br />
Make sure to explore the project and let us know what you think.</p>
<div class="ct-github-link"><a href="https://github.com/codrops/SliderPagination/">Find this project on GitHub</a></div>
<p><a class="demo" href="http://tympanus.net/Development/SliderPagination/">View demo</a> <a class="download" href="http://tympanus.net/Development/SliderPagination/SliderPagination.zip">Download source</a></p>
]]></content:encoded>
			<wfw:commentRss>http://tympanus.net/codrops/2012/12/21/slider-pagination-concept/feed/</wfw:commentRss>
		<slash:comments>30</slash:comments>
		</item>
		<item>
		<title>Sticky Captions Concept</title>
		<link>http://tympanus.net/codrops/2012/12/13/sticky-captions-concept/</link>
		<comments>http://tympanus.net/codrops/2012/12/13/sticky-captions-concept/#comments</comments>
		<pubDate>Thu, 13 Dec 2012 14:32:58 +0000</pubDate>
		<dc:creator>Mary Lou</dc:creator>
				<category><![CDATA[Playground]]></category>
		<category><![CDATA[caption]]></category>
		<category><![CDATA[CSS3]]></category>
		<category><![CDATA[hover]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[sticky]]></category>
		<category><![CDATA[thumbnail]]></category>

		<guid isPermaLink="false">http://tympanus.net/codrops/?p=12813</guid>
		<description><![CDATA[A little trick on how to make captions of thumbnails or items "sticky" in order to stay visible in the window or viewport.]]></description>
				<content:encoded><![CDATA[<p><a href="http://tympanus.net/Development/StickyCaptionsConcept/"><img src="http://codropspz.tympanus.netdna-cdn.com/codrops/wp-content/uploads/2012/12/StickyCaptionsConcept.jpg" alt="Sticky Captions Concept" title="Sticky Captions Concept" width="580" height="315" class="alignnone size-full wp-image-12815" /></a></p>
<p><a class="demo" href="http://tympanus.net/Development/StickyCaptionsConcept/">View demo</a> <a class="download" href="http://tympanus.net/Development/StickyCaptionsConcept/StickyCaptionsConcept.zip">Download source</a></p>
<p>When creating thumbnail grids, we usually want to show image captions on hover to provide more information about the item. Image captions are usually shown in a very specific part of the thumbnail, either on the top, the middle or the bottom. When adding captions to the bottom of a thumbnail it can happen that a thumbnail that is overflowing the viewport (i.e. is partly beyond the &#8220;fold&#8221;) is being hovered but the caption won&#8217;t be seen because it appears on the bottom part of the image that is not visible. The user would have to scroll the page in order to see the bottom of the item and eventually the caption. </p>
<p>A small trick can solve that problem by simply making the caption &#8220;sticky&#8221;. This would mean that the caption will be visible not only at the bottom of every thumbnail but also in any place, sticking at the bottom of the page, if the thumbnail hovered is overflowing the current view. </p>
<p>What we basically do is to imitate <strong>position: sticky</strong> but since it&#8217;s not yet supported in many browsers, we&#8217;ll do a bit of JavaScript to achieve the same result. We&#8217;ll be using jQuery. </p>
<p>The main idea is to see when a hovered element overflows the viewport and show the caption in the right place by changing its position from absolute to <em>fixed</em>.</p>
<p>As an example, let&#8217;s take a simple grid with figures and figcaptions:</p>
<pre class="brush:html">
&lt;div class="grid clearfix" id="grid"&gt;

	&lt;figure&gt;
		&lt;img src="images/4.jpg"&gt;
		&lt;figcaption&gt;
			&lt;a href="http://drbl.in/fWMT"&gt;Fall 7 Times Stand Up 8&lt;/a&gt; by Erika Mackley
		&lt;/figcaption&gt;
	&lt;/figure&gt;

	&lt;figure&gt;&lt;!-- ... --&gt;&lt;/figure&gt;
	&lt;figure&gt;&lt;!-- ... --&gt;&lt;/figure&gt;
	&lt;figure&gt;&lt;!-- ... --&gt;&lt;/figure&gt;
	&lt;!-- ... --&gt;
	
&lt;/div&gt;
</pre>
<p>In our demo we use <a href="http://masonry.desandro.com/" target="_blank">jQuery Masonry</a> for creating a neat grid.</p>
<div class="ct-ad-article-wrapper ct-ad-article-wrapper-in"><div class="ct-ad-article"><img class="ct-ad-img" src="http://codropspz.tympanus.netdna-cdn.com/codrops/wp-content/themes/codropstheme02/images/advertisement.jpg" /><div id="bsap_1279993" class="bsarocks bsap_af25dfd2f1908889af7a1aa5f4dcbd9e"></div><div style="clear:both;"></div></div></div>
<p>Let&#8217;s take a look at the structural styling of the figcaption element (to see all the styles, take a look at the style.css). The caption should be absolute and we will set a left of auto. This is important because when we switch to fixed positioning, we want the caption to start at the left of its parent container. We set a bottom value of -60 pixels in order to hide the caption (minus its own height). Note that the parent container needs to have its overflow set to &#8220;hidden&#8221;.</p>
<p>We also add a little transition which will animate the bottom to 0 when we hover over the figure:</p>
<pre class="brush:css">
.grid figure figcaption {
	position: absolute;
	left: auto;
	width: 100%;
	height: 60px;
	bottom: -60px;
	transition: bottom 0.2s ease-in-out;
}

.grid figure:hover figcaption {
	bottom: 0px;
}
</pre>
<p>Now, we want to check if the thumbnail that is being hovered is cut off at the bottom, i.e. out of the window view. If yes, we will change the caption position to fixed and set a width to it (otherwise it would just happily expand until the end of the page). </p>
<p>Let&#8217;s start by creating a custom jQuery selector called <strong>:bottomInViewport</strong> that we will help us determine if the caption of the image should be rendered or not. </p>
<pre class="brush:js">
$.extend( $.expr[':'], {
	bottomInViewport : function( el ) {
		var scrollTop = ( document.documentElement.scrollTop || document.body.scrollTop ),
			elOffsetTop = $( el ).offset().top,
			elH = $( el ).height(),
			descrH = $( el ).find( 'figcaption' ).outerHeight(true),
			winH = ( window.innerHeight &#038;&#038; window.innerHeight < $( window ).height() ) ? window.innerHeight : $( window ).height();

		return ( elOffsetTop + elH > scrollTop &#038;&#038; elOffsetTop + elH < scrollTop + winH ) || ( scrollTop + winH - elOffsetTop < descrH );
	}
});
</pre>
<p>The function returns true if the element is completely inside the viewport, meaning that the bottom part is not cut off. It also returns true if the element is not in the viewport but the visible part is just too small to fit the caption. In these cases our script shouldn't do anything and the caption will simply show as usual. If the function returns false, we will show the caption by setting its position to fixed. Since we defined the bottom to be 0 in the CSS, it will show at the bottom of the page, right where we need it. We'll also have to set the width to its parent's width (the figure):</p>
<pre class="brush:js">
function changeToFixed( $description, itemWidth ) {
	$description.css({ position: 'fixed', width: itemWidth });
}

function resetStyle( $description, delay ) {
	setTimeout( function() { $description.css({ position: 'absolute', width: '100%'}); }, delay || 0 );
}
</pre>
<p>We will need to bind the mouseenter and mouseleave events to the items and also the scroll event to the window while hovering over an item:</p>
<pre class="brush:js">
$items.on( 'mouseenter mouseleave', function( event ) {

	var $item = $( this ), itemWidth = $item.width(),
		$description = $item.find( 'figcaption' );

	switch( event.type ) {
		case 'mouseenter' :

			if( !$item.is( ':bottomInViewport' ) ) {
				$item.data( 'sticky', true );
				changeToFixed( $description, itemWidth );
			}
			
			$( window ).on( 'scroll', function () {
				var inviewport = $item.is( ':bottomInViewport' );
				if( !inviewport &#038;&#038; !$item.data( 'sticky' ) ) {
					$item.data( 'sticky', true );
					changeToFixed( $description, itemWidth );
				}
				else if( inviewport &#038;&#038; $item.data( 'sticky' ) ) {
					$item.data( 'sticky', false );
					resetStyle( $description );
				}
			} );

			break;
		
		case 'mouseleave' :

			if( $item.data( 'sticky' ) ) {
				$item.data( 'sticky', false );
				resetStyle( $( this ).find( 'figcaption' ), 200 );
			}
			$( window ).off( 'scroll' );
			break;
	}

} );
</pre>
<p>When we hover over an item, we check if we should apply our trick or not. Also, we bind the scroll event to the window, where we will check if the trick should be applied or reset as we scroll. When we leave the item, we unbind the scroll event from the window and we reset the item's style (if the trick was previously applied to it).</p>
<p>And that's it! Take a look at the demo and hover over an item that is cut off at the bottom to see the effect. And then scroll. You will see how the caption sticks at the bottom until its "natural" position is reached.</p>
<p><em>I hope you enjoyed this little trick and find it useful!</em></p>
<p><strong>Credits: the demo features <a href="http://dribbble.com/ErikaMackley">Dribbble shots</a> of illustrations by <a href="http://erikanoeldesign.com/">Erika Mackley</a>.</strong></p>
<p><a class="demo" href="http://tympanus.net/Development/StickyCaptionsConcept/">View demo</a> <a class="download" href="http://tympanus.net/Development/StickyCaptionsConcept/StickyCaptionsConcept.zip">Download source</a></p>
]]></content:encoded>
			<wfw:commentRss>http://tympanus.net/codrops/2012/12/13/sticky-captions-concept/feed/</wfw:commentRss>
		<slash:comments>16</slash:comments>
		</item>
		<item>
		<title>Fullscreen Pageflip Layout</title>
		<link>http://tympanus.net/codrops/2012/12/11/fullscreen-pageflip-layout/</link>
		<comments>http://tympanus.net/codrops/2012/12/11/fullscreen-pageflip-layout/#comments</comments>
		<pubDate>Tue, 11 Dec 2012 09:27:10 +0000</pubDate>
		<dc:creator>Mary Lou</dc:creator>
				<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[3d]]></category>
		<category><![CDATA[bookblock]]></category>
		<category><![CDATA[fullscreen]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[pageflip]]></category>

		<guid isPermaLink="false">http://tympanus.net/codrops/?p=12795</guid>
		<description><![CDATA[A tutorial on how to create a fullscreen pageflip layout using BookBlock. The idea is to flip the content like book pages and access the pages via a sidebar menu that will slide out from the left.]]></description>
				<content:encoded><![CDATA[<p><a href="http://tympanus.net/Tutorials/FullscreenBookBlock/"><img src="http://codropspz.tympanus.netdna-cdn.com/codrops/wp-content/uploads/2012/12/FullscreenBookBlock.jpg" alt="Fullscreen Pageflip Layout with BookBlock" title="Fullscreen Pageflip Layout with BookBlock" width="580" height="315" class="alignnone size-full wp-image-12802" /></a></p>
<p><a class="demo" href="http://tympanus.net/Tutorials/FullscreenBookBlock/">View demo</a> <a class="download" href="http://tympanus.net/Tutorials/FullscreenBookBlock/FullscreenBookBlock.zip">Download source</a></p>
<p>We have received a couple of requests on how to use the <a href="http://tympanus.net/codrops/2012/09/03/bookblock-a-content-flip-plugin/">BookBlock plugin</a> in fullscreen. So, we decided to create a fullscreen layout, apply BookBlock to it and add a sidebar menu. We&#8217;ll show you how to customize BookBlock and use some available options for navigating the content.</p>
<p>The idea is to navigate the pages using the arrows or swiping the pages, and to slide out the menu when clicking on the menu button. The sidebar menu will contain links to different pages, i.e. the table of contents. When clicking on a table of contents entry, we&#8217;ll jump to the respective page. </p>
<p>We&#8217;ll also use <a href="http://jscrollpane.kelvinluck.com/">jScrollPane</a> by Kevin Luck to add a custom scrollbar for the content when needed.</p>
<div class="ct-special-box"><strong>Please note: CSS 3D transforms will only work in modern browsers that support those properties.</strong></div>
<p>The demo contains excerpts form the hilarious <a href="http://www.gutenberg.org/ebooks/41595">&#8220;The Funny Side of Physic&#8221;</a> by A. D. Crabtre from Project Gutenberg. </p>
<p>The following libraries and jQuery plugins will be used:</p>
<ol>
<li><a href="http://tympanus.net/codrops/2012/09/03/bookblock-a-content-flip-plugin/">BookBlock</a> by Pedro Botelho</li>
<li><a href="http://jquerypp.com/">Custom jQuery++</a> by Bitovi</li>
<li><a href="http://jscrollpane.kelvinluck.com/">jScrollPane</a> by Kevin Luck</li>
<li><a href="https://github.com/brandonaaron/jquery-mousewheel/">jQuery Mouse Wheel Plugin</a> by Brandon Aaron</li>
<li><a href="http://modernizr.com/">Custom Modernizr</a> (peek inside to see what this build includes)</li>
</ol>
<p>So, let&#8217;s get started!</p>
<h3>The Markup</h3>
<p>Let&#8217;s have a main container for all our elements. Inside, we&#8217;ll add a division for the sidebar menu which we&#8217;ll give the class &#8220;menu-panel&#8221;, and the wrapper for the BookBlock with the class &#8220;bb-custom-wrapper&#8221;. The BookBlock will contain the wrapper (that we&#8217;ll apply the plugin to) and the structure that the plugin needs. Inside of each item, we&#8217;ll add a content wrapper with a division that we&#8217;ll need for the custom scroll functionality:</p>
<pre class="brush:html">
&lt;div id="container" class="container"&gt;	

	&lt;div class="menu-panel"&gt;
		&lt;h3&gt;Table of Contents&lt;/h3&gt;
		&lt;ul id="menu-toc" class="menu-toc"&gt;
			&lt;li class="menu-toc-current"&gt;&lt;a href="#item1"&gt;Self-destruction&lt;/a&gt;&lt;/li&gt;
			&lt;li&gt;&lt;a href="#item2"&gt;Why we die&lt;/a&gt;&lt;/li&gt;
			&lt;li&gt;&lt;a href="#item3"&gt;The honeymoon&lt;/a&gt;&lt;/li&gt;
			&lt;li&gt;&lt;a href="#item4"&gt;A drawing joke&lt;/a&gt;&lt;/li&gt;
			&lt;li&gt;&lt;a href="#item5"&gt;Commencing practice&lt;/a&gt;&lt;/li&gt;
		&lt;/ul&gt;
	&lt;/div&gt;

	&lt;div class="bb-custom-wrapper"&gt;

		&lt;div id="bb-bookblock" class="bb-bookblock"&gt;

			&lt;div class="bb-item" id="item1"&gt;
				&lt;div class="content"&gt;
					&lt;div class="scroller"&gt;
						&lt;h2&gt;Self-destruction&lt;/h2&gt;
						&lt;p&gt;...&lt;/p&gt;
					&lt;/div&gt;
				&lt;/div&gt;&lt;!-- /content --&gt;
			&lt;/div&gt;&lt;!-- /bb-item --&gt;

			&lt;div class="bb-item" id="item2"&gt;&lt;!-- ... --&gt;&lt;/div&gt;

			&lt;div class="bb-item" id="item3"&gt;&lt;!-- ... --&gt;&lt;/div&gt;

			&lt;div class="bb-item" id="item4"&gt;&lt;!-- ... --&gt;&lt;/div&gt;

			&lt;div class="bb-item" id="item5"&gt;&lt;!-- ... --&gt;&lt;/div&gt;

		&lt;/div&gt;&lt;!-- /bb-bookblock --&gt;
		
		&lt;nav&gt;
			&lt;a id="bb-nav-prev" href="#"&gt;&larr;&lt;/a&gt;
			&lt;a id="bb-nav-next" href="#"&gt;&rarr;&lt;/a&gt;
		&lt;/nav&gt;

		&lt;span id="tblcontents" class="menu-button"&gt;Table of Contents&lt;/span&gt;

	&lt;/div&gt;&lt;!-- /bb-custom-wrapper --&gt;

&lt;/div&gt;&lt;!-- /container --&gt;
</pre>
<p>The menu items will point to the respective BookBlock pages (bb-item). We&#8217;ll also add navigation arrows and a button for toggling the opening and closing of the menu.</p>
<p>Let&#8217;s move on to the style. </p>
<div class="ct-ad-article-wrapper ct-ad-article-wrapper-in"><div class="ct-ad-article"><img class="ct-ad-img" src="http://codropspz.tympanus.netdna-cdn.com/codrops/wp-content/themes/codropstheme02/images/advertisement.jpg" /><div id="bsap_1279993" class="bsarocks bsap_af25dfd2f1908889af7a1aa5f4dcbd9e"></div><div style="clear:both;"></div></div></div>
<h3>The CSS</h3>
<p><em>Note that we won&#8217;t use any vendor specific prefixes here, but you&#8217;ll find them in the files.</em></p>
<p>We don&#8217;t discuss the style of the BookBlock plugin here (you can find the styles in bookblock.css), instead we&#8217;ll focus on all the other styles that are important for the layout and customize a couple of things.</p>
<p>Let&#8217;s start by importing the Lato font from <a href="http://www.google.com/webfonts">Google web fonts</a>:</p>
<pre class="brush:css">
@import url(http://fonts.googleapis.com/css?family=Lato:300,400,700);
</pre>
<p>The html element should have a height of 100% since we will need to set the heights of absolute elements inside to expand to the window&#8217;s height:</p>
<pre class="brush:css">
html { 
	height: 100%; 
}
</pre>
<p>Let&#8217;s use <a href="http://paulirish.com/2012/box-sizing-border-box-ftw/">border-box</a> for box-sizing which will allow us to define percentages for widths and heights of elements while using paddings, without worrying about oversizing elements:</p>
<pre class="brush:css">
*,
*:after,
*:before {
	-webkit-box-sizing: border-box;
	-moz-box-sizing: border-box;
	box-sizing: border-box;
	padding: 0;
	margin: 0;
}
</pre>
<p>(We are brutally resetting the paddings in margins of all elements; you don&#8217;t have to do that, instead you could just normalize the respective elements.)</p>
<p>Let&#8217;s define the font for the body and set it&#8217;s height to 100%. Remember, we need to set it because of the children that will be absolute and 100% in height as well:</p>
<pre class="brush:css">
body {
	font-family: 'Lato', Calibri, Arial, sans-serif;
	font-weight: 400;
	font-size: 100%;
	color: #333;
	height: 100%;
}
</pre>
<p>We are using Modernizr and we&#8217;ve added the class &#8220;no-js&#8221; to the html element. When JavaScript is enabled, Modernizr will replace that class with &#8220;js&#8221;. This will allow us to give certain CSS properties to elements that we don&#8217;t want if JavaScript is disabled. Our 100% width and height layout only makes sense if we have JS enabled and only then we want the body to have its overflow hidden:</p>
<pre class="brush:css">
.js body {
	overflow: hidden;
}
</pre>
<p>Let&#8217;s define some link styles:</p>
<pre class="brush:css">
a {
	color: #555;
	text-decoration: none;
}

a:hover {
	color: #000;
}
</pre>
<p>We want our main container to occupy all the window width and height. The sidebar menu will be positioned outside of it by setting a negative left value (of its own width). The idea is to animate the whole container when we click to open the menu. It will slide to the right revealing the overflown sidebar menu.</p>
<p>So, let&#8217;s set the main wrappers&#8217; widths and heights to 100% and add a transition to the container:</p>
<pre class="brush:css">
.container,
.bb-custom-wrapper,
.bb-bookblock {
	width: 100%;
	height: 100%;
}

.container {
	position: relative;
	left: 0px;
	transition: left 0.3s ease-in-out;
}
</pre>
<p>When we click on the menu button, we will add another class to the container which will set the left to 240 pixels (width of the sidebar menu):</p>
<pre class="brush:css">
.slideRight {
	left: 240px;
}
</pre>
<p>Without JavaScript enabled, we won&#8217;t be able to do this, so let&#8217;s add a left padding instead:</p>
<pre class="brush:css">
.no-js .container {
	padding-left: 240px;
}
</pre>
<p>By default, we want the sidebar menu to be fixed to the left side:</p>
<pre class="brush:css">
.menu-panel {
	background: #f1103a;
	width: 240px;
	height: 100%;
	position: fixed;
	z-index: 1000;
	top: 0;
	left: 0;
	text-shadow: 0 1px 1px rgba(0,0,0,0.1);
}
</pre>
<p>When JS is enabled, we&#8217;ll set the position to absolute and the left to -240 pixel:</p>
<pre class="brush:css">
.js .menu-panel {
	position: absolute;
	left: -240px;
}
</pre>
<p>Let&#8217;s style the elements of the menu:</p>
<pre class="brush:css">
.menu-panel h3 {
	font-size: 1.8em;
	padding: 20px;
	font-weight: 300;
	color: #fff;
	box-shadow: inset 0 -1px 0 rgba(0,0,0,0.05);
} 

.menu-toc {
	list-style: none;
}

.menu-toc li a {
	display: block;
	color: #fff;
	font-size: 1.1em;
	line-height: 3.5;
	padding: 0 20px;
	cursor: pointer;
	background: #f1103a;
	border-bottom: 1px solid #dd1338;
}

.menu-toc li a:hover,
.menu-toc li.menu-toc-current a{
	background: #dd1338;
}
</pre>
<p>The navigation will be positioned absolutely on top of everything:</p>
<pre class="brush:css">
.bb-custom-wrapper nav {
	top: 20px;
	left: 60px;
	position: absolute;
	z-index: 1000;
}
</pre>
<p>The arrow links and the menu button will also be positioned absolutely and we&#8217;ll make them round by setting the border-radius to 50%:</p>
<pre class="brush:css">
.bb-custom-wrapper nav span,
.menu-button {
	position: absolute;
	width: 32px;
	height: 32px;
	top: 0;
	left: 0;
	background: #f1103a;
	border-radius: 50%;
	color: #fff;
	line-height: 30px;
	text-align: center;
	speak: none;
	font-weight: bold;
	cursor: pointer;
}

.bb-custom-wrapper nav span:last-child {
	left: 40px;
}

.bb-custom-wrapper nav span:hover,
.menu-button:hover {
	background: #000;
}
</pre>
<p>The menu button will be positioned in the top left corner and we&#8217;ll hide its text:</p>
<pre class="brush:css">
.menu-button {
	z-index: 1000;
	left: 20px;
	top: 20px;
	text-indent: -9000px;
}
</pre>
<p>Let&#8217;s create a little menu icon by using a pseudo-element with a double box shadow for the upper and lower line:</p>
<pre class="brush:css">
.menu-button:after {
	position: absolute;
	content: '';
	width: 50%;
	height: 2px;
	background: #fff;
	top: 50%;
	margin-top: -1px;
	left: 25%;
	box-shadow: 0 -4px #fff, 0 4px #fff;
}
</pre>
<p>In case that there is no JS enabled, we don&#8217;t need any of those elements, so we&#8217;ll simply hide them:</p>
<pre class="brush:css">
.no-js .bb-custom-wrapper nav span,
.no-js .menu-button {
	display: none;
}
</pre>
<p>Let&#8217;s move to the inner parts of the BookBlock items. The content division needs to be absolute and we&#8217;ll set the overflow to hidden. This is important because we want to apply our custom scroll here and we&#8217;ll only do that when a page was turned. If we wouldn&#8217;t set the overflow to hidden, we&#8217;d see the content overflowing. Again, this only makes sense when we have JS enabled, so we&#8217;ll add the &#8220;js&#8221; class:</p>
<pre class="brush:css">
.js .content {
	position: absolute;
	top: 60px;
	left: 0;
	bottom: 50px;
	width: 100%;
	overflow: hidden;
}
</pre>
<p>The scroller div is the one that will grow with content, so let&#8217;s set some paddings here:</p>
<pre class="brush:css">
.scroller {
	padding: 10px 5% 10px 5%;
}
</pre>
<p>Using percentages as lateral padding will make the layout adjust liquidly to the screen size.</p>
<p>Let&#8217;s hide those sharp edges when we scroll by adding pseudo-elements with a white to transparent gradient to the top and the bottom of the content div:</p>
<pre class="brush:css">
.js .content:before,
.js .content:after {
	content: '';
	position: absolute;
	top: 0;
	left: 0;
	width: 100%;
	height: 20px;
	z-index: 100;
	pointer-events: none;
	background: 
		linear-gradient(
			to bottom, 
			rgba(255,255,255,1) 0%, 
			rgba(255,255,255,0) 100%
		);
}

.js .content:after {
	top: auto;
	bottom: 0;
	background: 
		linear-gradient(
			to top, 
			rgba(255,255,255,1) 0%, 
			rgba(255,255,255,0) 100%
		);
}
</pre>
<p>This will make the text appear slightly faded out.</p>
<p>Let&#8217;s style the text elements:</p>
<pre class="brush:css">
.content h2 {
	font-weight: 300;
	font-size: 4em;
	padding: 0 0 10px;
	color: #333;
	margin: 0 1% 40px;
	text-align: left;
	box-shadow: 0 10px 0 rgba(0,0,0,0.02);
	text-shadow: 0 0 2px #fff;
}

.no-js .content h2 {
	padding: 40px 1% 20px;
}

.content p {
	font-size: 1.2em;
	line-height: 1.6;
	font-weight: 300;
	padding: 5px 8%;
	text-align: justify;
}
</pre>
<p>Finally, let&#8217;s add some media queries. Without JavaScript enabled, we don&#8217;t want to show the menu anymore from 800 pixels on. This is just an example of how we can control these elements under certain conditions. </p>
<p>The last media query will resize the font a bit, for smaller devices. <a href="http://css-tricks.com/why-ems/" target="_blank">Using ems</a> makes things easier for these cases.</p>
<pre class="brush:css">

@media screen and (max-width: 800px){
	.no-js .menu-panel {
		display: none;
	}

	.no-js .container {
		padding: 0;
	}
}

@media screen and (max-width: 400px){
	.menu-panel,
	.content {
		font-size: 75%;
	}
}
</pre>
<p>And that was all the style! Let&#8217;s add some <a href="http://youtu.be/Zdz88MBWomo" target="_blank" title="James Brown gives you dancing lessons">funky dance moves</a>, shall we?</p>
<h3>The JavaScript</h3>
<p>We will start by caching some elements and initializing the BookBlock plugin. We need to set some things after each page flip, mainly the current item&#8217;s index and the jScrollPane behavior. This is specified in the <strong>onEndFlip</strong> callback passed to the BookBlock.</p>
<pre class="brush:js">
var $container = $( '#container' ),

	// the element we will apply the BookBlock plugin to
	$bookBlock = $( '#bb-bookblock' ),

	// the BookBlock items (bb-item)
	$items = $bookBlock.children(),

	// index of the current item
	current = 0,

	// initialize the BookBlock
	bb = $( '#bb-bookblock' ).bookblock( {
		speed : 800,
		perspective : 2000,
		shadowSides	: 0.8,
		shadowFlip	: 0.4,
		// after each flip...
		onEndFlip : function(old, page, isLimit) {
			
			// update the current value
			current = page;

			// update the selected item of the table of contents (TOC)
			updateTOC();

			// show and/or hide the navigation arrows
			updateNavigation( isLimit );

			// initialize the jScrollPane on the content div for the new item
			setJSP( 'init' );

			// destroy jScrollPane on the content div for the old item
			setJSP( 'destroy', old );

		}
	} ),
	// the navigation arrows
	$navNext = $( '#bb-nav-next' ),
	$navPrev = $( '#bb-nav-prev' ).hide(),

	// the table of content items
	$menuItems = $container.find( 'ul.menu-toc > li' ),

	// button to open the TOC
	$tblcontents = $( '#tblcontents' ),

	transEndEventNames = {
		'WebkitTransition': 'webkitTransitionEnd',
		'MozTransition': 'transitionend',
		'OTransition': 'oTransitionEnd',
		'msTransition': 'MSTransitionEnd',
		'transition': 'transitionend'
	},

	// transition event name
	transEndEventName = transEndEventNames[Modernizr.prefixed('transition')],

	// check if transitions are supported
	supportTransitions = Modernizr.csstransitions;
</pre>
<p>First, let&#8217;s bind the events to some of the elements initialized before. Also, we need to initialize the jScrollPane for the first (current) item.</p>
<pre class="brush:js">
function init() {

	// initialize jScrollPane on the content div of the first item
	setJSP( 'init' );
	initEvents();

}
</pre>
<p>Since we&#8217;ll eventually need to initialize, reinitialize and destroy the jScrollPane, let&#8217;s define a function for this:</p>
<pre class="brush:js">
function setJSP( action, idx ) {
		
	var idx = idx === undefined ? current : idx,
		$content = $items.eq( idx ).children( 'div.content' ),
		apiJSP = $content.data( 'jsp' );
	
	if( action === 'init' &#038;&#038; apiJSP === undefined ) {
		$content.jScrollPane({verticalGutter : 0, hideFocus : true });
	}
	else if( action === 'reinit' &#038;&#038; apiJSP !== undefined ) {
		apiJSP.reinitialise();
	}
	else if( action === 'destroy' &#038;&#038; apiJSP !== undefined ) {
		apiJSP.destroy();
	}

}
</pre>
<p>We will need to bind several events:</p>
<ol>
<li>We will call the BookBlock&#8217;s next() and prev() methods when we click the navigation arrows or when swiping the page</li>
<li>The TOC will be shown / hidden when we click the $tblcontents (menu) button</li>
<li>We will call the BookBlock jump() method when we click a TOC item</li>
<li>The jScrollPane will be initialized on window resize</li>
</ol>
<p>So, here we go:</p>
<pre class="brush:js">
function initEvents() {

	// add navigation events
	$navNext.on( 'click', function() {
		bb.next();
		return false;
	} );

	$navPrev.on( 'click', function() {
		bb.prev();
		return false;
	} );
	
	// add swipe events
	$items.on( {
		'swipeleft'		: function( event ) {
			if( $container.data( 'opened' ) ) {
				return false;
			}
			bb.next();
			return false;
		},
		'swiperight'	: function( event ) {
			if( $container.data( 'opened' ) ) {
				return false;
			}
			bb.prev();
			return false;
		}
	} );

	// show TOC
	$tblcontents.on( 'click', toggleTOC );

	// click a menu item
	$menuItems.on( 'click', function() {

		var $el = $( this ),
			idx = $el.index(),
			jump = function() {
				bb.jump( idx + 1 );
			};
		
		current !== idx ? closeTOC( jump ) : closeTOC();

		return false;
		
	} );

	// reinit jScrollPane on window resize
	$( window ).on( 'debouncedresize', function() {
		// reinitialise jScrollPane on the content div
		setJSP( 'reinit' );
	} );

}
</pre>
<p>The navigation arrows&#8217; visibility will depend on the current page. If we are on the first page we&#8217;ll only see the next arrow and if we are on the last page we&#8217;ll only see the previous arrow:</p>
<pre class="brush:js">
function updateNavigation( isLastPage ) {
	
	if( current === 0 ) {
		$navNext.show();
		$navPrev.hide();
	}
	else if( isLastPage ) {
		$navNext.hide();
		$navPrev.show();
	}
	else {
		$navNext.show();
		$navPrev.show();
	}

}
</pre>
<p>When we open the TOC we want to hide the navigation arrows and we just show them again after closing the TOC.<br />
We will animate the sidebar menu with a CSS transition. If there&#8217;s no support for transitions then a simple show/hide fallback will be used:</p>
<pre class="brush:js">
function toggleTOC() {
	var opened = $container.data( 'opened' );
	opened ? closeTOC() : openTOC();
}

function openTOC() {
	$navNext.hide();
	$navPrev.hide();
	$container.addClass( 'slideRight' ).data( 'opened', true );
}

function closeTOC( callback ) {

	$navNext.show();
	$navPrev.show();
	$container.removeClass( 'slideRight' ).data( 'opened', false );
	if( callback ) {
		if( supportTransitions ) {
			$container.on( transEndEventName, function() {
				$( this ).off( transEndEventName );
				callback.call();
			} );
		}
		else {
			callback.call();
		}
	}

}
</pre>
<p>Phew! :) That&#8217;s it! I hope you enjoyed this tutorial and find it useful!</p>
<p><a class="demo" href="http://tympanus.net/Tutorials/FullscreenBookBlock/">View demo</a> <a class="download" href="http://tympanus.net/Tutorials/FullscreenBookBlock/FullscreenBookBlock.zip">Download source</a></p>
]]></content:encoded>
			<wfw:commentRss>http://tympanus.net/codrops/2012/12/11/fullscreen-pageflip-layout/feed/</wfw:commentRss>
		<slash:comments>96</slash:comments>
		</item>
	</channel>
</rss>

<!-- Performance optimized by W3 Total Cache. Learn more: http://www.w3-edge.com/wordpress-plugins/

Minified using disk: basic
Page Caching using disk: enhanced
Database Caching 15/19 queries in 0.011 seconds using disk: basic
Content Delivery Network via codropspz.tympanus.netdna-cdn.com

 Served from: tympanus.net @ 2013-05-23 17:37:18 by W3 Total Cache -->