Fixed Background Scrolling Layout

A fixed background image scrolling layout with 100% height panels and smooth scrolling.

Blueprint_ScrollingLayout

View demo Download source

A simple scrolling layout with fixed background images using background-attachment: fixed and a navigation. The page will scroll smoothly to the selected section.

The HTML

<div id="cbp-fbscroller" class="cbp-fbscroller">
	<nav>
		<a href="#fbsection1" class="cbp-fbcurrent">Section 1</a>
		<a href="#fbsection2">Section 2</a>
		<a href="#fbsection3">Section 3</a>
		<a href="#fbsection4">Section 4</a>
		<a href="#fbsection5">Section 5</a>
	</nav>
	<section id="fbsection1"></section>
	<section id="fbsection2"></section>
	<section id="fbsection3"></section>
	<section id="fbsection4"></section>
	<section id="fbsection5"></section>
</div>

The CSS

/* Set all parents to full height */
html, body, 
.container,
.cbp-fbscroller,
.cbp-fbscroller section { 
	height: 100%; 
}

/* The nav is fixed on the right side  and we center it by translating it 50% 
(we don't know it's height so we can't use the negative margin trick) */
.cbp-fbscroller > nav {
	position: fixed;
	z-index: 9999;
	right: 100px;
	top: 50%;
	-webkit-transform: translateY(-50%);
	-moz-transform: translateY(-50%);
	-ms-transform: translateY(-50%);
	transform: translateY(-50%);
}

.cbp-fbscroller > nav a {
	display: block;
	position: relative;
	color: transparent;
	height: 50px;
}

.cbp-fbscroller > nav a:after {
	content: '';
	position: absolute;
	width: 24px;
	height: 24px;
	border-radius: 50%;
	border: 4px solid #fff;
}

.cbp-fbscroller > nav a:hover:after {
	background: rgba(255,255,255,0.6);
}

.cbp-fbscroller > nav a.cbp-fbcurrent:after {
	background: #fff;
}

/* background-attachment does the trick */
.cbp-fbscroller section {
	position: relative;
	background-position: top center;
	background-repeat: no-repeat;
	background-size: cover;
	background-attachment: fixed;
}

#fbsection1 {
	background-image: url(../images/1.jpg);
}

#fbsection2 {
	background-image: url(../images/2.jpg);
}

#fbsection3 {
	background-image: url(../images/3.jpg);
}

#fbsection4 {
	background-image: url(../images/4.jpg);
}

#fbsection5 {
	background-image: url(../images/5.jpg);
}

The JavaScript

/**
 * cbpFixedScrollLayout.js v1.0.0
 * http://www.codrops.com
 *
 * Licensed under the MIT license.
 * http://www.opensource.org/licenses/mit-license.php
 * 
 * Copyright 2013, Codrops
 * http://www.codrops.com
 */
var cbpFixedScrollLayout = (function() {

	// cache and initialize some values
	var config = {
		// the cbp-fbscroller´s sections
		$sections : $( '#cbp-fbscroller > section' ),
		// the navigation links
		$navlinks : $( '#cbp-fbscroller > nav:first > a' ),
		// index of current link / section
		currentLink : 0,
		// the body element
		$body : $( 'html, body' ),
		// the body animation speed
		animspeed : 650,
		// the body animation easing (jquery easing)
		animeasing : 'easeInOutExpo'
	};

	function init() {

		// click on a navigation link: the body is scrolled to the position of the respective section
		config.$navlinks.on( 'click', function() {
			scrollAnim( config.$sections.eq( $( this ).index() ).offset().top );
			return false;
		} );

		// 2 waypoints defined:
		// First one when we scroll down: the current navigation link gets updated. 
		// A `new section´ is reached when it occupies more than 70% of the viewport
		// Second one when we scroll up: the current navigation link gets updated. 
		// A `new section´ is reached when it occupies more than 70% of the viewport
		config.$sections.waypoint( function( direction ) {
			if( direction === 'down' ) { changeNav( $( this ) ); }
		}, { offset: '30%' } ).waypoint( function( direction ) {
			if( direction === 'up' ) { changeNav( $( this ) ); }
		}, { offset: '-30%' } );

		// on window resize: the body is scrolled to the position of the current section
		$( window ).on( 'debouncedresize', function() {
			scrollAnim( config.$sections.eq( config.currentLink ).offset().top );
		} );
		
	}

	// update the current navigation link
	function changeNav( $section ) {
		config.$navlinks.eq( config.currentLink ).removeClass( 'cbp-fbcurrent' );
		config.currentLink = $section.index( 'section' );
		config.$navlinks.eq( config.currentLink ).addClass( 'cbp-fbcurrent' );
	}

	// function to scroll / animate the body
	function scrollAnim( top ) {
		config.$body.stop().animate( { scrollTop : top }, config.animspeed, config.animeasing );
	}

	return { init : init };

})();

View demo Download source

Previous:
Next:

Tagged with:

ML is a freelance web designer and developer with a passion for interaction design. She studied Cognitive Science and Computational Logic and has a weakness for the smell of freshly ground peppercorns.

View all contributions by

Website: http://www.codrops.com

Related Articles

Receive our bi-weekly Collective or blog updates right in your inbox.

Which newsletter would you like to receive?

CSS Reference

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

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