1. Web Design
  2. HTML/CSS
  3. JavaScript for Designers

Create a Parallax Scrolling Website Using Stellar.js

Scroll to top

One of the biggest trends in recent modern web design is use of parallax scrolling effects. In this tutorial I'm going to show you how you can create the effect on your own website, with a bit of imagination and a little help from Stellar.js.

A Modern Parallax jQuery Plugin

Interested in saving some time and making sure you're using modern best practices? There's a great responsive jQuery slider plugin on Envato Market that could do the job perfectly! It's already used on over 150,000 websites. 


Introduction

The parallax scrolling effect has been popular ever since sites such as Nike's Better World introduced it on their websites a few years ago. The parallax effect with regard to interfaces has been around since the 1980's when it was first used in video game titles and subsequently in games themselves. More recently it started to make an appearance in web interfaces - you'll be familiar with silverbackapp which used the effect as part of the header.

When combined with the scrolling functionality of a website, parallax scrolling effects can have a strong visual impact, especially when combined with some form of story which takes you on a journey.


Para...What?

Parallax is a displacement or difference in the apparent position of an object viewed along two different lines of sight. - Wikipedia

So what exactly is the parallax effect? Well it's probably one of the things that your clients refer to when they blindly say "I want my site HTML5". Whenever clients ask me for an "HTML5" site, I have to ask them specifically how they interpret the meaning HTML5 - at the moment it just seems to be the buzzword that clients keep saying to me without really understanding what it means.

So is it HTML5? Sure HTML5 does have a part to play in the parallax scrolling effect but it's more than HTML5, it also utilizes some form of javascript, such as jQuery, and wouldn't be possible without a little bit of CSS3.

The actual word parallax is derived from the Greek παραλλαξη (parallaxis) which means alteration. Objects which are closer to the eye have a larger parallax than objects which are in the distance. This means that objects which are closer to us can appear to move faster than objects in the background.

Layering up multiple backgrounds and objects (such as images) and then allowing them to move at different speeds creates a sensation of depth and dimension.


Parallax in Action

Take a look at some examples which demonstrate parallax effects.

SauconySauconySaucony
Lois JeansLois JeansLois Jeans
Nike Jump manNike Jump manNike Jump man
Bomb girlsBomb girlsBomb girls
TokiolabTokiolabTokiolab
IntactoIntactoIntacto

Every Website Tells a Story

The examples above all take you on some form of journey or story, and they do so in a variety of different ways. This, in my opinion, is what makes a parallax scrolling site a success. The key to making it interesting and unique is by focussing on a good story and concept, then using the effect in creative and imaginative ways.

Wieden+Kennedy (W&K), the guys behind the Nike Better World Website support this:

In our opinion, technologies are independent of concept. Our primary focus was on creating a great interactive storytelling experience. - Wieden+Kennedy (W&K)


How Our Site Will Work

To demonstrate one way of implementing parallax scrolling into your website I've opted to show you a simple four slide website that uses the effect on different backgrounds and images. I've also added a navigation in the left hand corner which will scroll to a specific slide on the site and will also change size to reflect the active slide number. I'm also using the web font Bebas, though you're free to use something else if you wish.

Here's how our folder structure will appear:

parallax website folder structureparallax website folder structureparallax website folder structure

The Plugins Used

Stellar.js

To help me achieve this I'm using the Stellar.js, a jquery plugin by Mark Dalgleish which makes it easy to create parallax scrolling sites. There are other plugins available to help you do this which I've listed at the bottom of this article. I've opted to use Stellar.js as it's fairly straightforward to implement and, although not demonstrated during this tutorial, it can be optimized to work on smart device platforms such as iOS.

Waypoints.js

I'm also going to use jQuery waypoints by Caleb Troughton. Waypoints is another jQuery plugin which executes a function whenever you scroll to an element. This allows the navigation on the site to highlight which slide we are on according to the position of the scrollbar.

jQuery Easing

jQuery easing is a plugin from GSGD which offers advanced easing options. We will be using this to add a nice easing movement when transitioning from slide to slide.


The HTML Markup

Kicking off our index.html we add the HTML5 doctype and then create the head section. This consists of a CSS Reset followed by our style sheet 'styles.css'. We then add the jQuery library followed by our custom jQuery file 'js.js'. This is then followed by the three plugins, 'jquery.stellar.min.js','waypoints.min.js' and 'jquery.easing.1.3.js'.

1
<!DOCTYPE HTML>
2
<html>
3
<head>
4
<meta charset="utf-8">
5
<title>Create a parallax Website using Stellar.js</title>
6
7
<link rel="stylesheet" type="text/css" href="http://yui.yahooapis.com/3.3.0/build/cssreset/reset-min.css">
8
<link rel="stylesheet" type="text/css" href="css/style.css">
9
10
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
11
<script type="text/javascript" src="js/js.js"></script>
12
<script type="text/javascript" src="js/jquery.stellar.min.js"></script>
13
<script type="text/javascript" src="js/waypoints.min.js"></script>
14
<script type="text/javascript" src="js/jquery.easing.1.3.js"></script>
15
16
</head>

The next element in our html is the image of the Envato logo which remains in a constant fixed position throughout the whole site. To this we add a class of 'envatologo' so that we can set the positioning of it later when we code up the CSS.

1
<img class="envatologo" src="images/envatologo.png">

The Slides

The four slides use the same markup:

1
  	
2
	<div class="slide" id="slide1" data-slide="1" data-stellar-background-ratio="0.5">  		  		  		
3
		<a class="button" data-slide="2" title=""></a>  	
4
	</div><!--End Slide 1-->

We use a class of 'slide' that will be used as a general style for all the slides. Each slide is then given an id of 'slide' followed by the slide number ie 'Slide1'. We use the HTML5 data attribute and name it 'data-slide'. This will allow us to target it using jQuery. Another data attribute of 'data-stellar-background-ratio' is added. This is specific to the stellar.js jQuery plugin and tells the plugin at what ratio the speed of the element should scroll.

The ratio is relative to the natural scroll speed, so a ratio of 0.5 would cause the element to scroll at half-speed, a ratio of 1 would have no effect, and a ratio of 2 would cause the element to scroll at twice the speed.

All slides except for slide four have a button that will allow us to scroll to the next slide. To this we add the 'data-slide' attribute with the value of the next slide number. This is so the button knows what slide is next so that we can pass this value to jQuery. The majority of the slides also have a span with a class of 'slideno'; simply a large text version of the slide number which appears in the bottom left hand corner of most slides. This could also be used for titles.

1
<span class="slideno">Slide 1</span>

On slides three and four we also add some image elements to the 'slide' div. These images will give a real insight into the parallax effect that we are creating. We wrap these inside a 'wrapper' div that will be centralized and is '960px' wide, this is just to ensure that it displays OK across all desktop monitor sizes.

Each image has a 'data-stellar-ratio' attribute attached to it. This again is stellar.js specific and tells the plugin at what ratio of speed we should scroll the element at.

1
<div class="wrapper">
2
		
3
			<img src="images/slide3/freelance.png" data-stellar-ratio="1.4" data-stellar-vertical-offset="-102"alt="">
4
			<img src="images/slide3/psdtuts.png" data-stellar-ratio="1.5" data-stellar-vertical-offset="-53"alt="">
5
			<img src="images/slide3/rockable.png" data-stellar-ratio="2.7" data-stellar-vertical-offset="-200"alt="">
6
			<img src="images/slide3/themeforest.png" data-stellar-ratio="3" data-stellar-vertical-offset="-200"alt="">
7
			<img src="images/slide3/tutshub.png" data-stellar-ratio="1" data-stellar-vertical-offset="-200"alt="">
8
			<img src="images/slide3/psdtuts.png" data-stellar-ratio="1.5" data-stellar-vertical-offset="-200"alt="">
9
10
</div>

The CSS

Luckily for us there's not too much involved with the CSS. It's basically styling a few simple elements, but the majority of it is for positioning some of the image elements.

The first thing we need to do with our CSS is bring in the BEBAS font using @font-face. We then add that to the html to set the font for the site. We also set the width and height of the html and body to 100%. This will allow our slides to adopt the full width and height of the user's screen.

1
  
2
@font-face {  
3
	font-family: 'BebasRegular';  
4
	src: url('font/BEBAS___-webfont.eot');  
5
	src: url('font/BEBAS___-webfont.eot?#iefix') format('embedded-opentype'),     
6
	url('font/BEBAS___-webfont.woff') format('woff'),     
7
	url('font/BEBAS___-webfont.ttf') format('truetype'),     
8
	url('font/BEBAS___-webfont.svg#BebasRegular') format('svg');  
9
	font-weight: normal;  
10
	font-style: normal;  
11
	}  
12
	
13
html,body{ 
14
	font-family: 'BebasRegular';  	
15
	width:100%;  	
16
	height:100%;  
17
}

The Navigation

The main navigation is given a 'fixed' position to keep it in the same place throughout the site. We offset this 20px from the top to give a little bit of space above it and set the z-index to 1 to ensure that this is on the top layer of the site.

The actual list is just the styling of the text with a border across the bottom to act as an underline. This has a width of 53px. A transition is also added so that it animates from its standard state to its hover state. I've used the -webkit- prefix here just to keep the code short, but the full source code which can be downloaded above contains all vendor prefixes.

The hover state also uses the same properties as the class 'active'; basically just an increase in font size and width. The 'active' class is used by jQuery to style the relevant slide which is in view of the browser window.

1
  
2
.navigation {  	
3
	position:fixed;  	
4
	z-index:1;  	
5
	top:20px;  
6
}  
7
.navigation li {  	
8
	color:#333333;  	
9
	display:block;  	
10
	padding: 0 10px;  	
11
	line-height:30px;  	
12
	margin-bottom:2px;  	
13
	font-weight:bold;  	
14
	-webkit-transition: all .2s ease-in-out;  	
15
	border-bottom:1px solid black;  	
16
	text-align:left;  	
17
	width:53px;  
18
}  
19
.navigation li:hover,
20
.active {  	
21
	font-size:25px;  	
22
	cursor:pointer;  	
23
	width:100px!important;  
24
}

The envato logo is given some positioning styles just to ensure that it remains in the centre of the screen. Similarly to the navigation this is also given a z-index of '1' to ensure it stays on top.

1
  
2
.envatologo {  
3
	position:fixed;  
4
	top:50%;  
5
	left:50%;  
6
	width:446px;  
7
	margin-top:-41px;  
8
	margin-left:-223px;  
9
	z-index:1;  
10
}

Now we move onto styling of the actual slides. We give them a background-attachment 'fixed' property. The background-attachment property sets whether a background image is fixed or scrolls with the rest of the page, so comes in useful for background-images (such as used on slide four). For this example we've used a wallpaper by Philipp Seiffert which can be downloaded here. We set the position of the slide to 'relative'. This is to that we can absolutely position the classes 'slideno' and 'button' against the slide as opposed the actual document.

The box shadow is purely for decoration purposes and adds a nice drop shadow to the top inset of each slide.

1
.slide {
2
	background-attachment: fixed;
3
	width:100%;
4
	height:100%;
5
	position: relative;
6
	box-shadow:inset 0px 10px 10px rgba(0,0,0,0.3);
7
}
8
.wrapper {
9
	width:960px;
10
	height:200px;
11
	margin:0 auto;
12
	position:relative;
13
}
14
.slideno {
15
	position:absolute;
16
	bottom:0px;
17
	left:0px;
18
	font-size:100px;
19
	font-weight:bold;
20
	color:rgba(255,255,255,0.3);
21
}

The .button is for the button at the bottom of the page which allows us to progress to the next slide. We've positioned it at the bottom centre of each slide and have used an image of an arrow as the indicator.

1
.button{
2
	display:block;
3
	width:50px;
4
	height:50px;
5
	position:absolute;
6
	bottom:0px;
7
	left:50%;
8
	background-color:#333333;
9
	background-image:url(../images/arrow.png);
10
	background-repeat:no-repeat;
11
}
12
.button:hover{
13
	background-color:#494949;
14
	cursor:pointer;
15
}

The styling for each individual slide is relatively simple and follows the same pattern each time. Slide one has a background color of '#5c9900'. Slide two also has a background color set on it. Slide two also contains images and we can target each one by using the CSS Selector nth-child(n). This selector can be described as

This pseudo-class matches elements on the basis of their positions within a parent element's list of child elements.

So we're basically styling each image in the order they appear in our markup. We're simply positioning them relative to the wrapper of the slide.

1
/******************************

2
 SLIDE 1 

3
*******************************/
4
#slide1{
5
	background-color:#5c9900;
6
	
7
}
8
/******************************

9
 SLIDE 2 

10
*******************************/
11
#slide2{
12
	background-color:#005c99;
13
	
14
}
15
#slide2 img:first-child{
16
	position:absolute;
17
top: 700px;
18
left: -150px;
19
}
20
#slide2 img:nth-child(2){
21
	position:absolute;
22
	top:300px;
23
	left:100px;
24
}
25
#slide2 img:nth-child(3){
26
	position:absolute;
27
	top:600px;
28
	left:300px;
29
}
30
#slide2 img:nth-child(4){
31
	position:absolute;
32
	top:400px;
33
	left:300px;
34
}
35
#slide2 img:nth-child(5){
36
	position:absolute;
37
	top:600px;
38
	right:300px;
39
}
40
#slide2 img:nth-child(6){
41
	position:absolute;
42
	top:600px;
43
	right:300px;
44
}
45
#slide2 img:nth-child(7){
46
	position:absolute;
47
	top:400px;
48
	right:100px;
49
}
50
#slide2 img:nth-child(8){
51
	position:absolute;
52
	top:100px;
53
	right:300px;
54
}

Slide three follows the same suit as slide two.

1
  
2
/****************************** SLIDE 3 *******************************/  
3
#slide3 {  	
4
	background-color:#b6c10b;  
5
}  
6
#slide3 img:first-child {  	
7
	position:absolute;  
8
	top: 700px;  
9
	left: 300px; 
10
}  
11
#slide3 img:nth-child(2){  	
12
	position:absolute;  	
13
	top:100px;  	
14
	left:100px;  
15
}  
16
#slide3 img:nth-child(3){  	
17
	position:absolute;  	
18
	top:150px;  	
19
	left:300px;  
20
}  
21
#slide3 img:nth-child(4){  	
22
	position:absolute;  	
23
	top:450px;  	
24
	left:300px; 
25
}  
26
#slide3 img:nth-child(5){  	
27
	position:absolute;  	
28
	top:200px;  	
29
	right:300px;  
30
}  
31
#slide3 img:nth-child(6){  	
32
	position:absolute;  	
33
	top:100px;  	
34
	right:300px;  
35
}

Slide four is slightly different than the previous two slides as it doesn't contain any image elements or a background-color, but instead uses a background-image. We've also given it the CSS3 property 'background-size:cover'. This basically sets the background-image to cover the entire browser window and will resize as the browser window resizes. We have also added a line of text on the last slide which we have styled and given a class of 'parallaxbg'

1
/******************************

2
 SLIDE 4 

3
*******************************/
4
5
#slide4{
6
	background-image:url(../images/Slide4/desktop4.jpg);
7
	-webkit-background-size: cover;
8
	-moz-background-size: cover;
9
	-o-background-size: cover;
10
	background-size: cover;
11
}
12
#slide4 .parallaxbg{
13
	position:absolute;
14
	right:40px;
15
	top:40px;
16
	font-size:28px;
17
	color:rgba(51,51,51,0.3);
18
}

The jQuery

The jQuery really is where this thing starts to come to life. I've commented the code so that you can see exactly what is happening.

1
  
2
jQuery(document).ready(function ($) {
3
4
5
    //initialise Stellar.js

6
    $(window).stellar();
7
8
    //Cache some variables

9
    var links = $('.navigation').find('li');
10
    slide = $('.slide');
11
    button = $('.button');
12
    mywindow = $(window);
13
    htmlbody = $('html,body');
14
15
16
    //Setup waypoints plugin

17
    slide.waypoint(function (event, direction) {
18
19
        //cache the variable of the data-slide attribute associated with each slide

20
        dataslide = $(this).attr('data-slide');
21
22
        //If the user scrolls up change the navigation link that has the same data-slide attribute as the slide to active and 

23
        //remove the active class from the previous navigation link 

24
        if (direction === 'down') {
25
            $('.navigation li[data-slide="' + dataslide + '"]').addClass('active').prev().removeClass('active');
26
        }
27
        // else If the user scrolls down change the navigation link that has the same data-slide attribute as the slide to active and 

28
        //remove the active class from the next navigation link 

29
        else {
30
            $('.navigation li[data-slide="' + dataslide + '"]').addClass('active').next().removeClass('active');
31
        }
32
33
    });
34
35
    //waypoints doesnt detect the first slide when user scrolls back up to the top so we add this little bit of code, that removes the class 

36
    //from navigation link slide 2 and adds it to navigation link slide 1. 

37
    mywindow.scroll(function () {
38
        if (mywindow.scrollTop() == 0) {
39
            $('.navigation li[data-slide="1"]').addClass('active');
40
            $('.navigation li[data-slide="2"]').removeClass('active');
41
        }
42
    });
43
44
    //Create a function that will be passed a slide number and then will scroll to that slide using jquerys animate. The Jquery

45
    //easing plugin is also used, so we passed in the easing method of 'easeInOutQuint' which is available throught the plugin.

46
    function goToByScroll(dataslide) {
47
        htmlbody.animate({
48
            scrollTop: $('.slide[data-slide="' + dataslide + '"]').offset().top
49
        }, 2000, 'easeInOutQuint');
50
    }
51
52
53
54
    //When the user clicks on the navigation links, get the data-slide attribute value of the link and pass that variable to the goToByScroll function

55
    links.click(function (e) {
56
        e.preventDefault();
57
        dataslide = $(this).attr('data-slide');
58
        goToByScroll(dataslide);
59
    });
60
61
    //When the user clicks on the button, get the get the data-slide attribute value of the button and pass that variable to the goToByScroll function

62
    button.click(function (e) {
63
        e.preventDefault();
64
        dataslide = $(this).attr('data-slide');
65
        goToByScroll(dataslide);
66
67
    });
68
69
70
});

Just a Few Points

Create a Parallax Scrolling Website using Stellarjs envatoCreate a Parallax Scrolling Website using Stellarjs envatoCreate a Parallax Scrolling Website using Stellarjs envato

If you look at slide two of our example, you will notice the 3D bubbles. I have added a slight gaussian blur to some of these, mainly to those at the very foreground and background. Combining these with sharply focused bubbles adds to the sense of depth that parallax creates. This is something that you should maybe consider when trying to get good depth to your site.

A lot of sites that utilize this effect do tend to be quite image heavy, make sure you compress your images as much as you can (without sacrificing quality). If after compression it's still taking quite a while to load then consider adding a loader to your site.


Conclusion

Parallax scrolling is one of the most loved effects of recent times and people are constantly pushing the boundaries with it. Here today I've shown you how to setup a basic website that utilizes parallax scrolling. The demo that I've shown today is a relatively simple site for learning purposes. For those of you who are about to create a site using this effect then I urge you to spend time on the concept and story as this is what makes them unique, shareable and indeed a pleasure to browse. It's about how you can utilize this effect wisely and not just using it for the sake of using it.

I hope you've enjoyed reading about parallax scrolling and I'd love to see how you guys have utilized it in your own sites, feel free to leave links to them below. Until next time!


Further Links Reading And Resources

Did you find this post useful?
Want a weekly email summary?
Subscribe below and we’ll send you a weekly email summary of all new Web Design tutorials. Never miss out on learning about the next big thing.
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.