How to Create a Beautiful Fullscreen Single Scrolling Page like Huge Inc

Huge Inc is a website that generated a great impact on its release in January 2014. Following the trends of the time, it used full screen sections with a minimalist look, but they went one step further, creating an original effect by combining the scroll hijacking technique with fixed backgrounds and a "normal site" placed underneath the sections.

Huge is one of the best design firms nowadays providing its services to companies such as Google and Apple and its website is nothing less than a reflection of their work.

Create the Huge Inc Page with pagePiling.js

Huge Inc

In this tutorial I’m going to explain step by step how to create a page with a very similar effect to Huge Inc by using the jQuery plugin pagePiling.js.

pagePiling.js

Introduction

If you take a quick look at the pagePiling.js demo website you might be wondering what do both sites have in common. Both use scroll hijack and full-page sections but… the effect looks different! Right?

Taking a deeper look into the Huge website you will notice how the text in each of the sections moves up or down when scrolling ending up fading out when reaching the top. Isn’t that exactly what happens when using pagePiling.js? Do you start seeing the similarity now?

It is only the image which stays static, and the text has exactly the same movement as in pagePiling.js. The trick is on the fixed backgrounds. Once we have that, we will only have to worry about the second problem. Create a “normal site” underneath the sections free from the scroll hijacking.

Creating Fixed Backgrounds

This is nothing new, by just using CSS we will be able to get it done. We will only need to make use of the background properties like so:

.section {
    /* the important one*/
    background-attachment: fixed; 

    background-size: auto 80%;
    background-position: 50% 0%;
    background-repeat: no-repeat;
}

We apply the styles over the .section class because it's the class I’m using for my sections in my example. Any other can be used, but I prefer to use the default class used by pagePiling.js. If you want to use any other class instead, remember to tell pagePiling.js by using the option sectionSelector ( i.e. sectionSelector: '.page')

background-attachment: fixed; is the property which will fix our background so it stays static in our viewport.

With background-size I’m just specifying the dimensions of my background for this example. Feel free to use cover for yours if it fits better with your design. Any other option can be used here.

And to have it centered, background-position: 50% 0%;. 50% horizontally and 0% vertically.

Now that we have the background properties defined, let's add a different image for each section:

#section1 {
    background-image: url(imgs/h1.jpg);
}
#section2 {
    background-image: url(imgs/h2.jpg);
}
#section3 {
    background-image: url(imgs/h3.jpg);
}

As you can see, I’m using different id names to distinguish between sections.

Our HTML should look like this right now:

<div class="section" id="section1"></div>
<div class="section" id="section2"></div>
<div class="section" id="section3"></div>
<div class="section" id="section4"></div>

But we need to wrap it into another element because that’s the way pagePiling needs it to be, so:

<div id="pagepiling">
    <div class="section" id="section1"></div>
    <div class="section" id="section2"></div>
    <div class="section" id="section3"></div>
    <div class="section" id="section4"></div>
</div>

Notice we didn’t add any background to the latest section because that’s the one which will contain our "normal content page".

Adding Content

This doesn’t require much explanation. I’m going to add a couple of sentences in the sections with backgrounds, just as in the Huge Inc website, and then I’ll add a larger text in the last section:

<div id="pagepiling">
    <div class="section" id="section1">
        <div class="intro">
            <h1>All business.</h1>
            <p>A new home for the word's most influencial management magazine.</p>
         </div>
    </div>
    <div class="section" id="section2">
        <div class="intro">
            <h1>Nike Making.</h1> 
            <p>Inspiring the creative community to make sustainable design choices.</p>
        </div>
    </div>
    <div class="section" id="section3">
         <div class="intro">
             <h1>Floored.</h1>
            <p>Clean, modern, and fast. Introducing the new Lexus.com.</p>
         </div>
    </div>
    <div class="section" id="section4">
        <div class="content">
            <p>My normal website</p>
            <p>My normal website</p>
            <p>My normal website</p>
            <p>My normal website</p>
            <p>My normal website</p>
            <p>My normal website</p>
            <p>My normal website</p>
            <p>My normal website</p>
        </div>
    </div>
</div>

I wrapped all text because we will need it later on, but basically it will make it easier to style and play with those elements in JavaScript.

Creating the Scrollable Section

pagePiling.js provides a simple way to force a section to be scrollable. It just needs to have the class pp-scrollable and like magic, it will provide us with a scroll bar and it won’t scroll to any other section until we reach the top or the bottom of its content.

We will slightly change our section4 declaration adding the necessary class:

<div class="section pp-scrollable" id="section4">

Seeing the Magic

Now, we just need to initialize the plugin:

$(document).ready(function () {
    $('#pagepiling').pagepiling({
        verticalCentered: false,
        css3: false,
    });
});

We feel forced to use the option css3:false because of a bug in Chrome when dealing with the CSS3 property translate3d and fixed backgrounds

Here we have what looks like a quite similar page to Huge Inc!!

But of course, we can still polish it more!

Taking Care of the Details

If you compare the achieved result with the Huge Inc site you’ll notice a couple of differences:

  • We still have navigation bullets in the last section
  • The way the last section is shown is not exactly the same as what they achieved at Huge Inc. Their content is sliding up and ours is static in the background while the previous section gets smaller to show it.
  • Our text doesn’t fade in or out
  • We don’t have a clickable arrow at the bottom of each section to move forward
  • We didn’t apply any styling to our text

So… lets solve all of them!

Removing Navigation Bullets in the Last Section

pagePiling provides us with some callbacks that come in very handy for things like this.

We will be using the callback onLeave for our case, so whenever we leave the 3rd section to reach our normal site, we will fade out the navigation bullets. And whenever we leave the last section, we will show them again.

Our callback should look like this:

onLeave: function (index, nextIndex, direction) {
    if (nextIndex == 4) {
        $('#pp-nav').fadeOut();
    }
    if (index == 4) {
        $('#pp-nav').fadeIn();
    }
}

And it will be placed in our pagePiling initialization like this:

$(document).ready(function () {
    $('#pagepiling').pagepiling({
        verticalCentered: false,
        css3: false,
        onLeave: function (index, nextIndex, direction) {
             //reaching our last section? The one with our normal site?
            if (nextIndex == 4) {
                $('#pp-nav').fadeOut();
            }

            //leaving our last section? The one with our normal site?
            if (index == 4) {
                $('#pp-nav').fadeIn();
            }
        },
    });
});

We are fading in and out the element with id #pp-nav because that’s the identifier used by pagePiling for it.

Sliding up the Last Section

This step can be a bit more tricky to think of in a first instance, but it is not that complicated.

As pagePiling piles our sections one over another, our last section will always be under the 3rd one and will always show its content whenever it leaves. But… what if we fire an action on leaving the 3rd section so that an element in the last section slides up just at the same time as the 3rd section does and at the same speed?

Then we will have the illusion of a 4th section sliding up! As the static content of the 4th section wouldn’t be visible because the sliding element in that section would be sliding up at the same speed as the previous section disappears.

Here’s a picture to illustrate it:

Viewport

In fact, this is more difficult to explain with words than with code, so lets go directly to the code!

First of all, we need to position our content just at the bottom of our last section, so we can slide it up later on:

#section4 .content {
    top: 100%;
    position: absolute;
    left: 0;
}

And now, using the same callback as before, onLeave, we will be animating it using the same scrollingSpeed used by default in pagePiling.js (700) and the same jQuery easing function (easeInQuart). To see the default values check pagePiling docs.

Here we go:

onLeave: function (index, nextIndex, direction) {
    //reaching our last section? The one with our normal site?
    if (nextIndex == 4) {
        //fading out navigation bullets
        $('#pp-nav').fadeOut();

        //sliding up the content
        $('#section4').find('.content').animate({
            top: '0%'
        }, 700, 'easeInQuart');
    }

    //leaving our last section? The one with our normal site?
    if (index == 4) {
        //fadding in navigation bullets
        $('#pp-nav').fadeIn();

        //sliding it down to its initial position
        $('#section4 .content').animate({
            top: '100%'
        }, 700, 'easeInQuart');
    }
},

Fading Text

Once again, we will use the callback onLeave and the help of jQuery to achieve this result:

onLeave: function (index, nextIndex, direction) {
    //fading out the text of the leaving section
    $('.section').eq(index - 1).find('h1, p').fadeOut(700, 'easeInQuart');

    //fading in the text of the destination (in case it was fadedOut)
    $('.section').eq(nextIndex - 1).find('h1, p').fadeIn(700, 'easeInQuart');
}

This should be added to our existing callback, so it would look like this:

        $(document).ready(function() {
            /*
            * Plugin intialization
            */
            $('#pagepiling').pagepiling({
                verticalCentered:false,
                css3:false,
                sectionsColor: ['white', '#E8E8E8', '#f2f2f2', '#EC008C'],
                onLeave: function(index, nextIndex, direction){

                    //fading out the txt of the leaving section
                    $('.section').eq(index -1).find('h1, p').fadeOut(700, 'easeInQuart');

                    //fading in the text of the destination (in case it was fadedOut)
                    $('.section').eq(nextIndex -1).find('h1, p').fadeIn(700, 'easeInQuart');


                    //reaching our last section? The one with our normal site?
                    if(nextIndex == 4){

                        //fading out navigation bullets
                        $('#pp-nav').fadeOut();

                        $('#section4').find('.content').animate({
                            top: '0%'
                        }, 700, 'easeInQuart');
                    }

                    //leaving our last section? The one with our normal site?
                    if(index == 4){
                        //fadding in navigation bullets
                        $('#pp-nav').fadeIn();

                        $('#section4 .content').animate({
                            top: '100%'
                        }, 700, 'easeInQuart');
                    }
                },
            });
        });
    </script>

Creating the Clickable Arrow

Clickable Arrow

As this is a matter of design, I will show here the style I will be using to replicate the same effect, but I won’t give any explanation about it.

I will add the following just after the opening <body> tag, but it could have been placed anywhere else, as it will be fixed:

    <button id="arrow">
        <span>↓</span>
    </button>

The following styles will be applied to those elements:

    #arrow{
        width: 100%;
        height: 50px;
        text-align: center;
        cursor: pointer;
        position: fixed;
        bottom: 0;
        left: 0;
        border: 0;
        outline: 0;
        z-index: 100;
        color: #BBB;
        background: transparent;
        -moz-transition: all 0.2s cubic-bezier(0.7, 0.01, 0.3, 1);
        -o-transition: all 0.2s cubic-bezier(0.7, 0.01, 0.3, 1);
        -webkit-transition: all 0.2s cubic-bezier(0.7, 0.01, 0.3, 1);
        transition: all 0.2s cubic-bezier(0.7, 0.01, 0.3, 1);
        font: 36px Heiti, 'Lucida Grande', Arial;
        font-weight: bold;
    }
    #arrow span{
        display: inline-block;
        position: relative;
        top: -18px;
        -moz-transition: all 0.7s cubic-bezier(0.7, 0.01, 0.3, 1);
        -o-transition: all 0.7s cubic-bezier(0.7, 0.01, 0.3, 1);
        -webkit-transition: all 0.7s cubic-bezier(0.7, 0.01, 0.3, 1);
        transition: all 0.7s cubic-bezier(0.7, 0.01, 0.3, 1);
    }
    #arrow:hover{
        background: #EC008C;
    }
    #arrow:hover span{
        top: 0;
        color: #FFF;
    }

And to link it with the action of scrolling a section down, we will be using the function moveSectionDown provided by pagePiling.js linked to a click event over the button:

$('#arrow').click(function () {
    $.fn.pagepiling.moveSectionDown();
});

A Touch of Style

And just to finish with our lovely website, we’ll style the headers and text a bit. This is basic CSS that won’t be explained in this tutorial:

/* Styling titles and text for the sections with backgrounds*/
.intro {
    position: absolute;
    bottom: 100px;
    text-align: center;
    width: 100%;
}
.intro h1 {
    font-size: 5em;
    font-weight: bold;
    color: #000;
}

/* Styling our last section, our content */
#section4 .intro {
    color: #000;
}
.page {
    width: 80%;
    margin: 60px auto;
    background:white;
    padding: 60px;
    -webkit-box-sizing: border-box;
    -moz-box-sizing: border-box;
    box-sizing: border-box;
}
.page p {
    font-style: 12px;
    margin: 20px 0 0 0;
    line-height: 1.35em;
    color: #333;
}

And that’s all!

I would say you can have a pretty good result by just using pagePiling.js default behavior and forgetting about the second half of the tutorial, but if you really want to achieve what Huge Inc did, then you will have to put a bit more effort into it and follow the whole procedure.

To make it simple for you guys, I will add links to CodePen so you can play with it more comfortably.

Opinions expressed in this article are those of the author and not necessarily those of Onextrapixel.