Unlocking the parallax effect with your grandchildren: A guide to creating memorable

I have successfully implemented the parallaxing background effect several times before on Codepen and in small, experimental projects.

My go-to tutorial for this technique is this one by Keith Clark.

Here is the structure outlined in the tutorial:

<div class="parallax">
  <div class="parallax__layer parallax__layer--back">
    ...
  </div>
  <div class="parallax__layer parallax__layer--base">
    ...
  </div>
</div>

Key CSS properties mentioned in the tutorial:

.parallax {
  ...
  perspective: 1px;
}
.parallax__layer--base {
  transform: translateZ(0);
}
.parallax__layer--back {
  transform: translateZ(-1px);
}

In essence, the .parallax element adds a sense of depth perception, enabling a 3D viewing experience.

The foreground layer .parallax__layer--base remains at its original position (z-axis: 0), while the background layer .parallax__layer--back slightly recedes along the z-axis.

As you scroll within the .parallax element, the layers' movement creates a visually appealing parallax effect.

However, what if we want to apply this effect on a larger, multi-section webpage?

<div class='home'>
...
  <div class="parallax">
    <div class="parallax__layer parallax__layer--back">
      ...
    </div>
    <div class="parallax__layer parallax__layer--base">
      ...
    </div>
  </div>
  ...
</div>

The CSS and markup structure remain unchanged. Now, as you scroll through the .home section, not the .parallax, the 3D space illusion still applies—albeit confined to the .perspective element's scope.

Is there a method to extend this perspective to the children or grandchildren of the homepage, or must each page division be individually segmented into foreground and background components to maintain the parallax effect?

Answer â„–1

I devised a creative workaround using JavaScript to achieve this.

Here is an outline of the steps (you can think of it as the algorithm):

  • Monitor the window scroll event
  • Wait until the parallax container (the parent of what you designated as base and back) is visible
  • In my scenario, I fixed back and adjusted the top value of base with a transition duration.

Below is my implementation (tailored to my specific use case):

/**
 * Creative parallax effect
 */
const viewportHeight =
  'innerHeight' in window
    ? window.innerHeight
    : document.documentElement.offsetHeight

const headerHeight = document.querySelector('header').offsetHeight

window.onscroll = () => {
  const preFooterPosition = document
    .querySelector('.pre-footer')
    .getBoundingClientRect()

  /** initiate parallax when pre-footer comes into view */
  if (
    preFooterPosition.top <= headerHeight &&
    preFooterPosition.bottom >= viewportHeight
  ) {
    // parallax
    document.querySelector('.content').classList.add('transform-content')
  } else {
    // reverse parallax
    document
      .querySelector('.content')
      .classList.remove('transform-content')
  }
}
.content {
  display: flex;
  flex-direction: column;
  flex: 1;
  z-index: 1;
  position: relative;
  top: 0;
  transition: top 1s ease;
}

.transform-content {
  top: -5rem;
}

.watermark {
  position: absolute;
  z-index: 0;
  flex: 1;
  display: flex;
}
<template>
  <section class="pre-footer">
    <div class="wrapper">
      <div class="watermark">
        <SVGIcon class="watermark-left" icon="LearnLongShort" />
        <SVGIcon class="watermark-right" icon="FreeEducation" />
      </div>
      <div class="content">
        <div class="content-left content-wrapper">
          <div>
            <h3 class="title">Evidence base</h3>
            <div class="body">
              <p>The Academy of Medical Cannabis Evidence Base is an advanced referencing tool for CBMP research. Containing the history of research to date and all emerging findings, this cutting-edge engine underpins our learning content.</p>
            </div>
            <WhiteButton text="View database" />
          </div>
        </div>
        <div class="content-right content-wrapper">
          <div>
            <h3 class="title">White Papers</h3>
            <div class="body">
              <p>Alongside our learning platform, The Academy publishes a series of authoritative papers discussing the core topics and themes related to CBMPs. Register to view and download the archive.</p>
            </div>
            <WhiteButton text="Archive" />
          </div>
        </div>
      </div>
    </div>
  </section>
</template>

I trust this proves useful. Do let me know if you discover a more elegant solution. Until then, I'm sticking with this method.

Cheers!

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Preventing a user with the same name as the one in the table from being added by utilizing a jQuery contains check proved

Check out my fiddle here: http://jsfiddle.net/jd5pgdz2/4/ I encountered an issue when attempting to add a user with the same name as one already in my table (the displayed users are static in the HTML). Despite using 'contains' to check if the u ...

Switching the background color in a diagonal transition when hovering from the bottom left to the top right

I found a helpful answer on this question regarding a certain technique. However, I am curious if it is feasible to implement a diagonal left-to-right background color transition - specifically from bottom-left to top-right? Here is the CSS and HTML code ...

Guide to saving a Python docx file on the client side with the help of Ajax

I am currently using Python 3.6 with Django, and my code snippet is shown below: from docx import Document document = Document() document.add_heading('My docx', 0) document.save('myFile.docx') return HttpResponse(document, content_typ ...

Save the user input to a dedicated text file

I am working with a couple of select tags that generate an array. Previously, I was only logging the array to the console upon pressing the SUBMIT button, but now I want to save it to a separate text file. Here is my main.html code: <form method="POS ...

Utilizing HTML snippets for AJAX integration

Let's dive in, I may be completely off track here. I am currently working with Wordpress. On a page I am creating an HTML select menu (Main Menu) with options that correspond to each page on the site. This menu is visible on the page. In addition, ...

Could my HTML security measures be vulnerable to exploitation?

I have successfully developed a function that accomplishes the following: It accepts a string as input, which can be either an entire HTML document or an HTML "snippet" (even if it's broken). It creates a DOMDocument from the input and iterates throu ...

Guide on making a prev/next | first/last button functional in list.js pagination

Is there a way to enhance my paginated index by adding prev/next, first/last buttons? I am curious if anyone has implemented these features using List.js. <script src='//cdnjs.cloudflare.com/ajax/libs/lodash.js/2.4.1/lodash.min.js&ap ...

JavaScript Document Object Model: Locate an element with a class that is either similar to or includes a specific substring

I am facing a situation where I need to locate a wrapper element with a specific class name that includes a random id, such as wp-rgtayfu-fxyjzw-wrapper. The class will always have the substring wrapper in it, and there is only one element in the document ...

Scrolling the inner container in a CSS flexbox layout: tips and tricks

I'm currently working on designing a flex box based HTML layout like the one shown in the image link provided below. https://i.stack.imgur.com/nBl6N.png The layout should consist of 3 rows within the viewport with the following structure: - top: " ...

In Outlook, images are always shown in their true dimensions

While everything is working perfectly fine in Gmail, Yahoo, and Hotmail, there seems to be an issue with the display of the logo image on Outlook. The custom width and height settings are not being applied properly, resulting in the logo being displayed ...

Why is it important to incorporate the CSS property background-repeat: repeat; into our code?

It is believed that if you don't expressly mention the background-repeat in CSS styling, browsers will automatically set it as background-repeat: repeat. With this default behavior in place, one might wonder why there is even a need for a separate ba ...

What is the best way to access the front camera on both Android and iOS devices in order to capture a photo using Vue.J

I am currently developing a PWA Vue.Js application and I am trying to implement a feature that allows users to take a picture with the front camera on their mobile devices. Although I have managed to write code that works on my desktop browser, I have bee ...

Checkboxes within Angular's reactive forms are a powerful tool for creating dynamic user

Currently, I am working on a contact form that includes checkboxes for users to select multiple options, with the requirement of selecting at least one box. My challenge lies in figuring out how to pass all the selected checkboxes' data to an API usin ...

Shifting a division using insertAfter

Hey there! I'm having a bit of trouble using the insertAfter function. In each product in my store, I need to position an "add to cart" button after the price. This is the code I tried: <Script type="text/javascript" > jQuery(document).read ...

Apply a specific style conditionally using Angular's ng-repeat directive

Currently, I am utilizing ng-repeat to iterate through a list of divs and manually adding items to the JSON that is rendering these divs. My goal is to position the last div that I add in the JSON at the location where the mouse cursor is, while keeping th ...

Is there a way to modify the background of a div when a specific field within my component is true and the div is being hovered over?

When I hover over a div, I want the background color to change. Additionally, I need the color choice to be based on an element within my component. <div *ngFor="let u of users;" [style:hover.background-color] = "u.selected ? 'red ...

"Incorporating date and time information into the database

I am attempting to set up an automatic SMS system that sends a reminder 24 hours before our residents' appointments. My challenge lies in extracting the date and time from the datetime row in my MySQL database. While I could create an input field, my ...

Changing the text color of Material UI Accordion Summary upon expansion

How can I update the color of an Accordion summary text in Material UI when it is expanded? <Accordion expanded={expanded === 'panel1'} onChange={handleChange('panel1')} className={classes.root}> <AccordionSummary ...

List with Columns for Organization

I am not seeking advice on how to use columns in lists, but rather on aligning the columns on my website. Below is the code I have: <ol class="threecolumns"> <li>Item 1</li> <li>Item 2</li> <li>Item 3< ...

Hover effect not activating on image within modal

only img:hover is working, but after adding this to the CSS: #user-profile #user-myModal .modal-body img:hover #user-profile #user-myModal .modal-body .change-pic i{ display: block; } it's not working. I changed the class and id names, tried eve ...