Implementing a parallax scroll effect using CSS and dynamically updating the background-position value with JavaScript

How can different Y position percentages be dynamically assigned to multiple layered background images in CSS using JavaScript so that they update as the page scrolls?

<style>
  body {
    background-image: 
      url(img/bg-pattern-01.png),
      url(img/bg-pattern-02.png),
      url(img/bg-pattern-03.png);
    background-position:
      center 45%,
      center 50%,
      center 55%;
  }
</style>

The example above shows static values (45%, 50%, 55%) as background positions, but these percentages should ideally change based on the vertical scroll position of the page. This could involve a combination or average blend of the actual scroll percentage.

Answer №1

Unique Parallax Scrolling Methodology

An insightful answer was provided for my question, which I accepted. However, the contributor has since removed their response. It served as a valuable reference point and guided me in refining the techniques to create what I had envisioned:

This innovative approach involves creating a multi-layered parallax scrolling background that adapts seamlessly to any window size without the need for additional DIV elements. The use of jQuery simplified the process significantly, although it could be replicated using vanilla JavaScript if necessary. The implementation is straightforward and not overly complex.

Innovative Conceptualization

The technique involves designing a multi-layered background with specified CSS styling, including defining the background-position. A script then adjusts the top or bottom position by subtracting a pixel value for each layer based on whether it belongs to the upper or lower part of the design.

The demo includes various background images along with their corresponding properties:

image background
-repeat
background
-size
background
-position
(initial)
background
-position
(scripted)
background
-blend
-mode
perceptual
layer *
repeat-x 100vw center bottom center bottom -${(scrollBtm * 0.9)}px lighten lay1:btm
(nearest)
repeat-x 100vw center bottom center bottom -${(scrollBtm * 0.6)}px normal lay2:btm
src repeat 33vw center top center top -${(scrollTop * 0.3)}px lighten particle anim **
repeat-x 100vw center top center top -${(scrollTop * 0.2)}px normal lay3:top
repeat-x 100vw center bottom center bottom -${(scrollBtm * 0.2)}px multiply lay3:btm
no-repeat cover center center center center
(not scripted)
normal
(always)
lay4
(farthest)

* = "Perceptual layer" denotes the perceived stacking order of layers in the design from the viewer's perspective, providing a useful way to track the arrangement. Use whatever labels suit your workflow.

** = The inclusion of an animated particle GIF was spontaneous and does not have a specific ordering rule. Hence, no perceptual layer number is assigned; however, it visually enhances the transition between lay2 and lay3.

A key aspect of this method is the utilization of scrollTop and scrollBottom functions to offset backgrounds relative to the page's top and bottom. Each perceptual layer (e.g., lay3) can feature both a top and bottom image for added depth.

The script dynamically repositions layers an adjustable distance (- amount px) away from the top or bottom of the page upon scrolling activity.

By tweaking the scroll rate multiplier (* ranging from 0.0 to 1.0), the movement speed relative to scrolling can be fine-tuned. Higher values (e.g., 0.9) create a closer perceived distance, while lower values (e.g., 0.1) result in objects appearing farther away. Layers sharing the same "perceptual layer" should maintain consistent scroll rates to maintain visual coherence.

Though not essential for every design, the example demonstrates the effective use of the background-blend-mode property for achieving more engaging visual effects.

After executing the code snippet, clicking Full Page is recommended to appreciate the full immersive impact.

Image Optimization Insights: While imgur (the hosting platform for the images in this demonstration) currently lacks support for WebP, utilizing this format can drastically reduce file sizes—my tests revealed WebP files are approximately 8% the size of PNG and still-image GIF backgrounds. The total size of all static images exported as WebP amounted to a mere 193KB, whereas a single animated GIF clocked in at a slightly heftier 254KB. Though optimization specifics may vary, prioritizing efficient compression formats like WebP and ensuring resource-intensive formats like animated GIFs are used judiciously can prevent unwieldy image file sizes in multi-layer designs. The crux is recognizing that employing streamlined compression methods across different elements contributes to the overall efficiency of the final design.

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

How to Maintain Spacing Between Two Elements While Ensuring the Right Element Stays to the Right Even if the First One is Hidden in CSS

Presently, I have two icons being displayed with a space between them using the flex-box property justify-content and value space-between. The issue arises when only one icon is displayed, as I need the V-icon to always remain on the left and the urgent-ic ...

Incorporating various vertical divs with 100% height and width

Struggling to achieve the creation of multiple divs with 100% width and height? Here is an example: <html> <body> <div id="wrapper"> <div id="1">100% height & width, all you can see when opening this file!</div&g ...

Utilize CSS to incorporate an image as the background of a <div> element

I'm a beginner in the world of HTML/CSS and this is my practice page. I have a section with an image of a person, and I'd like to add a quote next to the image. However, I'm struggling to make the image fill the entire width and height of th ...

Creating a collaborative storage space within a MERN project folder

Currently, I am developing an application using the MERN stack. The structure of my project repository includes both backend and frontend components: my-project/ ├── backend/ │ │ │ . │ . │ └── package.json ├── fronten ...

How can I move a nested child component out of an ancestor element with overflow set to hidden?

I'm facing an issue with a sliding carousel where the overflow-x property is set to hidden. The carousel displays 4 items at a time, and each item contains a button that triggers a pop-out menu positioned relative to its parent item. The problem arise ...

Velocity.js causing a slowdown in animated performance

Currently, I am attempting to animate spans, and while the animation is functional, it appears to be somewhat choppy and lacks smoothness. https://codepen.io/pokepim/pen/JBRoay My assumption is that this is due to my use of left/right for animation purpos ...

Using JavaScript to Filter JSON Objects

After making a php ajax call, I have received the following JSON data that needs to be displayed to the users: JSON {"headers":{},"body":"{\"comuni\":[{\"datapresub\":\"08\/08 ...

Unexpected issue encountered when working with JSON in Node.js

I've searched through countless solutions on stackoverflow, but none of them seem to work for me. It's really frustrating not understanding what's going wrong. Below is the code I'm having trouble with: var data = ""; req.on('dat ...

Child components are not able to access properties from the root component in VUE3

Hi there! I'm currently learning VUE3 and had a question about defining global properties in the Root Component. I did some research on Google before posting this question, but couldn't find any relevant results. I would like to set a global pro ...

Repetitive series of HTTP requests within a looping structure

Within my AngularJS project, I encounter the need to execute a varying number of HTTP requests in sequence. To achieve this, I believe that utilizing a loop is necessary: for (let i = 0; i < $scope.entities.length; i++) { MyService.createFixedValue ...

Why does my Redux callback keep getting invoked multiple times?

In developing a react application with redux, I have chosen to avoid using react-redux by manually handling all dispatched events. Below is a sample code snippet. The content of index.html <!DOCTYPE html> <html> <head> <script src=& ...

Appending an empty <li> tag has no effect

I'm facing an issue with this loop where it always generates empty <li></li> tags. Can anyone help me understand why this is happening and suggest a solution? For reference, the loop runs 2 times (verified). function a(){ for (var i ...

Unable to make anchor tag inside button effectively collapse another div

My Nuxt 2 SSR + Bootstrap 5 application includes the following code snippet: <button v-for="file of orderProduct.files" class="collapsed son-collapse" type="button" data-bs-toggle=&quo ...

CSS Opacity Issue

Why is the article transparent? Despite my efforts to search online for similar instances, I am surprised at not finding anything and feeling quite puzzled about what steps to take next. body { background-color: #000000; opacity: 0.8; background-i ...

Ways to extract certain characters from each element in an array

I'm attempting to make the first four characters of each element in an array (specifically a list) bold, but I am only able to select entire strings: $("li").slice(0).css("font-weight", "Bold"); Is there a way for me to indicate which characters wit ...

The 404 error is handled by the express application before continuing to other routes. Some routes may not be recognized by the express.Router module

Shown below is the content of app.js: var express = require('express'); var routes = require('./routes/index'); app = express(); app.use('/', routes); // catch 404 and forward to error handler app.use(function(req, res, next ...

A new value was replaced when assigning a JSON value inside a loop

Is there a way to generate a structure similar to this? { "drink": { "2": { "name": "coke", "type": "drink" }, "3": { "name": "coke", "type": "drink" } }, "food": ...

What is the best way to set inner text using jQuery?

The code snippet below demonstrates a specific issue: <span id="test1">some text</span> <span id="test2">some text</span> Upon loading the content, the following JavaScript is executed: alert($('test1').text(); $(' ...

Changing the templateUrl of a directive on the fly using the controller

How can I dynamically pass the templateUrl for the app_modal directive from the "ServerController" controller to allow for different templates for different modals? I have included the URL as an attribute in the "app-modal" tag used in the server_group.htm ...

Tips for executing parallax designs, similar to the techniques used on the

Currently, I am in the process of creating a website that utilizes parallax scrolling. Here is a brief overview of what I have accomplished thus far. I decided to use the skrollr plugin to achieve the desired parallax effect. Through this plugin, I was abl ...