WEEK: 11
Active: Not Currently Active
Work Due:

Parallax Scrolling

Another trend in web design of the past few years is known as “parallax scrolling”. Parallax, as a term refers to an optical phenomenon, in which the relation and position of two objects seems to change as the angle of viewing changes. This is caused by differences in depth of the objects.

This is the phenomenon that causes objects, which are far away from you, to appear as though they are moving relatively slower than close objects when you are driving in a car.

To understand this term more, browse through the wikipedia page on “Parallax”

In web design, the parallax effect is used to create background images that other content flows over, revealing them. We will refer to this as “parallax-like” as we will not really move the background image. A more complex example will use the effect to slowly move multiple background images.

Fake Parallax

Lets first look at creating a parallax-like effect. We will do this by building on our hero image example from the previous page.

First, we will set the background of the body element to use a full-size image.

Second, we will create a div-container (.description-container), which will be the width of the browser, and contain any content that will be placed over our background image. We need to specify a minimum height for this container so that we can guarantee that it is seen. We will set this to min-height: 50vh;. We are choosing 50vh as we will set the top and bottom margin of the containing content element to 25vh. This together will equal 100vh, which will make this section the same height as the browser window at a minimum. We use the min-height property, instead of height, so that element could grow larger, in situations, where the screen is so narrow, that the text takes up more vertical space than is possible in a 100vh block.

Third, we will create another div-container element (.description). This will hold any text we want to present over the background image. This element, as mentioned above, has its margin property set to margin: 25vh auto;. This sets the top and bottom margin to be a quarter of the height of the viewport, while centering the element left to right. We will also specify a width as a ratio of the screen, and a min-width, so that the element never gets too small. Finally, we also include a background, with an alpha value, so that the text is clearly legible over the background, but allows the background to easily be seen.

Finally, since this site accidentally became for a fake restaurant, the last section on this page is a menu section. This elements minimum height is also set to 100vh, which guarantees, that the element will be able to cover background.

Please study the following code, and look at the example (I would encourage you to view it in a separate window).

HTML
<body>

    <div class="hero">
        <div class="title">
            <h1>Chateua Musića</h1>
            <h2>Fine Al Fresco Dining</h2>
            <h2>On the private porch</h2>
            <div class="nav">
                <a href="#"><div class="nav-item">Hours</div></a>
                <a href="#"><div class="nav-item">About</div></a>
                <a href="#"><div class="nav-item">Location</div></a>
                <a href="#"><div class="nav-item">Menus</div></a>
            </div>
        </div>
    </div> <!--end hero-->

    <!-- Container that will "reveal" the background image. -->
    <!-- This is our parallax-like effect. -->
    <div class="description-container">
        <div class="description">

            <h1>A Night at Chateau Musića</h1>
            <p>You can expect only the finest cuisine, or locally poached buffaloe (we do not refer to these magestic animals as 'bison' here.)</p>
            <p>This animals, as representatives of the great plains of the North American Continent, are a true delicacy that we should all embrace and learn to enjoy.</p>

        </div>
    </div> <!-- End Parallax-Like -->

    <!-- A fake menu, this will re-cover the background image. -->
    <div class="menu">
        <h1>Seasonal Menu</h2>
        <div class="menu-group-container">

            <div class="menu-group">

                <div class="menu-head">Starters</div>
                <div>
                    <div class="menu-item">Fois Gras</div>
                    <div class="menu-item">Mushroom Ragout</div>
                    <div class="menu-item">Fried Rocky Mountain Oysters</div>
                </div>
            </div>
            <div class="menu-group">

                <div class="menu-head">Mains</div>
                <div>
                    <div class="menu-item">Buffalo Ravioli</div>
                    <div class="menu-item">Buffalo Skewers</div>
                    <div class="menu-item">Buffalo Pot Pie</div>
                </div>
            </div>
        </div>
    </div> <!-- End Menu -->

</body>
CSS
body {
    padding: 0;
    margin: 0;
    background-image: url("imgs/hero-image.jpg");
    background-attachment: fixed;
    background-repeat: no-repeat;
    background-size: cover;
    background-position: center;
    font-family: 'Josefin Sans', sans-serif;
    font-weight: 300;
}

/* Description Rules */
/* Parallax-Like Effect */
.description-container {
    min-height: 50vh;
    font-size: 2em;
}

.description {
    margin: 25vh auto;
    padding: 1em;
    text-align: center;
    width: 75%;
    min-width: 300px;
    background-color: rgba(210, 210, 210, 0.8);

}

@media (max-width: 865px) {
    .description-container {
        font-size: 1.5em;
    }
}

/* Hero Image Rules */
.hero {
    /* the 'vh' unit asks the browser to */
    /* return the height of the viewport */
    /* we can then use that to set the height of an element */
    /* as a percentage of the viewport height (vh) */
    height: 100vh;
    min-height: 740px;
    background-image: url("imgs/hero-image-2.jpg");
    background-position: center;
    background-repeat: no-repeat;
    background-size: cover;
    box-shadow: 0 4px 10px rgba(0, 0, 0, .8);
}

.hero .title {
    font-size: 22pt;
    color: #fff;
    float: right;
    margin-top: 170px;
    margin-left: 1em;
    margin-right: 1em;
    padding: 2em;
    text-align: center;
    background-color: rgba(120, 120, 120, 0.3);
}

.title h1 {
    font-family: 'Princess Sofia', cursive;
    font-size: 2.5em;
    letter-spacing: 0.2em;
}

.title h2 {
    font-family: 'Josefin Sans', sans-serif;
    font-weight: 300;
    font-style: italic;
    line-height: 0.5em;
}

.hero .nav {
    font-family: 'Josefin Sans', sans-serif;
    font-style: italic;
    font-weight: 300;
    color: #fff;
    margin-top: 2em;
    font-size: 1.5em;
    display: flex;
    flex-direction: row;
}

.hero .nav a {
    flex-grow: 1;
    color: #fff;
    text-decoration: none;
}

.hero .nav-item {
    font-size: 0.5em;
    padding: 0.5em 1em;
    margin: 0 0.5em;
    text-align: center;
    border: 1px solid #d9d9d9;
    border-width: 1px 0;
}

.hero .nav-item:hover {
    color: #fff;
    background-color: rgba(207, 200, 222, 0.5);
}


@media (max-width: 865px) {
    .hero {
        min-height: 730px;
    }
    .hero .title {
        font-size: 18pt;
    }
}

@media (max-width: 585px) {
    .hero {
        min-height: 500px;
    }
    .hero .title {
        font-size: 14pt;
        margin: 0;
        margin-top: 50px;
    }
}

@media (max-width: 445px) {
    .hero .title {
        font-size: 12pt;
    }
}

/* Menu Rules */
.menu {
    box-sizing: border-box;
    min-height: 100vh;
    padding: 2em;
    background-color: rgb(61, 61, 61);
    color: #fff;
    font-family: 'Josefin Sans', sans-serif;
    font-weight: 300;
    font-size: 1.5em;
    text-align: center;
    box-shadow: 0 -4px 10px rgba(0, 0, 0, .8);
}

.menu h1 {
    font-family: 'Princess Sofia', cursive;
}

.menu .menu-group-container {
    display: flex;
    flex-flow: row wrap;
    flex-grow: 1;
    justify-content: space-around;
}
.menu .menu-group {
    padding: 1em;
    min-width: 300px;
    max-width: 500px;
}

.menu .menu-head {
    font-style: italic;
    font-size: 2em;
    padding: 1em;
}

.menu .menu-item {
    text-align: left;
    font-style: normal;
}
[Code Download] [View on GitHub] [Live Example]

As you start to look around, you will notice that many sites use this effect. My own homepage, uses this to display a quote, while showing an image of me performing.

{ TODO: }

Read about implementing Parallax;

Multi-Image Parallax

Let’s next look at creating a page that uses multiple parallax background images. The following example is adapted from the w3schools demo, from the link above.

Notice, that each section that will utilize the parallax effect, is given a container div element, and the class corresponds to the background image (i.e. .bgimg-1, .bgimg-2, .bgimg-3).

Inside the CSS for these containers, they have been given;

  • position: relative;
  • background-attachment: fixed;
  • background-position: center;
  • background-size: cover;

The height and image url for each section are then set separately.

HTML
<body>

    <div class="bgimg-1">
        <div class="caption">
            <span class="border">SCROLL DOWN</span>
        </div>
    </div>

    <div class="hero">
        <h3 style="text-align:center;">Parallax Demo</h3>
        <p>Parallax scrolling is a web site trend where the background content is moved at a different speed than the foreground content while scrolling. Nascetur per nec posuere turpis, lectus nec libero turpis nunc at, sed posuere mollis ullamcorper libero ante lectus, blandit pellentesque a, magna turpis est sapien duis blandit dignissim. Viverra interdum mi magna mi, morbi sociis. Condimentum dui ipsum consequat morbi, curabitur aliquam pede, nullam vitae eu placerat eget et vehicula. Varius quisque non molestie dolor, nunc nisl dapibus vestibulum at, sodales tincidunt mauris ullamcorper, dapibus pulvinar, in in neque risus odio. Accumsan fringilla vulputate at quibusdam sociis eleifend, aenean maecenas vulputate, non id vehicula lorem mattis, ratione interdum sociis ornare. Suscipit proin magna cras vel, non sit platea sit, maecenas ante augue etiam maecenas, porta porttitor placerat leo.</p>
    </div>

    <div class="bgimg-2">
        <div class="caption">
            <span class="border">LESS HEIGHT</span>
        </div>
    </div>

    <div class="description-container">
        <div class="description">
            <p>Scroll up and down to really get the feeling of how Parallax Scrolling works.</p>
        </div>
    </div>

    <div class="bgimg-3">
        <div class="caption">
            <span class="border">SCROLL UP</span>
        </div>
    </div>

    <div class="description-container">
        <div class="description">
            <p>Scroll up and down to really get the feeling of how Parallax Scrolling works.</p>
        </div>
    </div>

    <div class="bgimg-1">
        <div class="caption">
            <span class="border">COOL!</span>
        </div>
    </div>

</body>
CSS
body {
    margin: 0;
    color: #777;
    font: 400 15px/1.8 "Lato", sans-serif;
}

.bgimg-1, .bgimg-2, .bgimg-3 {
    position: relative;
    opacity: 0.65;
    background-repeat: no-repeat;
    background-attachment: fixed;
    background-position: center;
    background-size: cover;
}

.bgimg-1 {
    min-height: 100vh;
    background-image: url("imgs/img_parallax.jpg");
}

.bgimg-2 {
    min-height: 400px;
    background-image: url("imgs/img_parallax2.jpg");
}

.bgimg-3 {
    min-height: 400px;
    background-image: url("imgs/img_parallax3.jpg");
}

.hero {
    padding: 50px 80px;
    color: #777;
    background-color: white;
    text-align: center;
    text-align: justify;
}

.caption {
    position: absolute;
    top: 50%;
    left: 0;
    width: 100%;
    color: #000;
    text-align: center;
}

.description-container {
    position: relative;
}

.description {
    padding: 50px 80px;
    color: #ddd;
    background-color: #282E34;
    text-align: center;
    text-align: justify;
}

.caption span.border {
    padding: 18px;
    color: #f7f7f7;
    background-color: #4a4a4a;
    font-size: 25px;
    letter-spacing: 10px;
}

h3 {
    color: #111;
    text-transform: uppercase;
    font: 20px "Lato", sans-serif;
    letter-spacing: 5px;
}


/* Turn off parallax scrolling for tablets and phones */
@media only screen and (max-device-width: 1024px) {
    .bgimg-1, .bgimg-2, .bgimg-3 {
        background-attachment: scroll;
    }
}
[Code Download] [View on GitHub] [Live Example]

True Parallax

True parallax allows the relative layers of the page to actually all scroll, at different rates, which achieves a sense of depth. This is captured, and demonstrated below in the following CodePen, which is a demo of the website for the game “Firewatch”. Notice how when you scroll on the demo, the various layers of trees move at individual rates.


See the Pen Firewatch Parallax in CSS by Sam Beckham (@samdbeckham) on CodePen.

To learn how to create this true parallax effect, please read the following articles;

{ TODO: }

Please also look at the following sites with collections of Parallax Sites, to get the creative juices flowing;


Previous section:
Next section: