What techniques can I use to generate a 3D visual effect by shifting the background image layer as the user scrolls (creating a Parallax effect

I have combined two images in the heading; one on top of the other. My goal is to create a subtle vertical movement in the background image as the user scrolls, giving the illusion of depth. Both images share the same width, but the background image is taller.

To view the website, please click here:

After doing some research on Google, I came across implementations using CSS and JavaScript to achieve this effect, known as the Parallax effect.

Initially, the bottom of the background image should line up with the bottom of the front image when the page is at the top. As the user continues scrolling downwards and the header image disappears, I would like the top of the background image to align with the top of the front image to enhance the 3D illusion.

The design is responsive, and it would be great if the effect works seamlessly on both mobile phones and desktops. However, desktop compatibility is crucial. If CSS proves to be impractical or too complex, implementing javascript can also be an option.

body {
  background: gray;
  font-size: 140%
}

.content {
  margin: 50px auto 0px auto;
  max-width: 1100px;
  padding-bottom: 2000px;
  padding-top: 30px;
  background-color: white;
  border: solid black;
  border-width: 0px 16px 0px 16px;
}

.margin-content {
  margin: 30px 80px 0px 100px;
}

.header-img {
  width: 100%;
  background-image: url("https://i.stack.imgur.com/r6CD4.jpg");
  background-size: contain;
}
<div class="content">
  <div class="margin-content">
    <h1> My Brand </h1>
  </div>
  <img src="https://i.stack.imgur.com/uxvh2.png" class="header-img" />
  <div class="margin-content">
    <h2>Lorem ipsum dolor sit amet..</h2>
    <p>..consectetur adipiscing elit. Fusce ex erat, vehicula vitae sapien vel, dignissim ornare odio.</p>
  </div>
</div>
</div>
<p style="color:white;text-align: center; position: relative; top:13px">© 2048 My Brand</p>

Any assistance provided will be greatly valued! :)

Answer №1

If you're looking to achieve this effect, there are a couple of approaches you can take.

The first method involves simply setting background-attachment: fixed;, which ensures that the background image remains stationary as you scroll. Additionally, you can include the following CSS properties:

background-size: cover;
background-repeat: no-repeat;
background-position: center;

body {
  background: gray;
  font-size: 140%
}

.content {
  margin: 50px auto 0px auto;
  max-width: 1100px;
  padding-bottom: 2000px;
  padding-top: 30px;
  background-color: white;
  border: solid black;
  border-width: 0px 16px 0px 16px;
}

.margin-content {
  margin: 30px 80px 0px 100px;
}

.header-img {
  width: 100%;
  background-image: url("https://i.stack.imgur.com/r6CD4.jpg");
  background-size: cover;
  background-repeat: no-repeat;
  background-position: center;
  background-attachment: fixed;
}
<div class="content">
  <div class="margin-content">
    <h1> My Brand </h1>
  </div>
  <img src="https://i.stack.imgur.com/uxvh2.png" class="header-img" />
  <div class="margin-content">
    <h2>Lorem ipsum dolor sit amet..</h2>
    <p>..consectetur adipiscing elit. Fusce ex erat, vehicula vitae sapien vel, dignissim ornare odio.</p>
  </div>
</div>
<!--</div>-->
<p style="color:white;text-align: center; position: relative; top:13px">© 2048 My Brand</p>

Alternatively, you can implement a JavaScript solution for a more dynamic effect. This script utilizes a parallax effect on background images, enhancing the scrolling experience. To complement this approach, adjust the following CSS attributes:

background-size: 150%;
background-repeat: no-repeat;
background-position: center;

When using background-size: cover or background-size: contain, proper scrolling may be impeded due to sizing constraints. By enlarging the image slightly compared to its container, smooth scrolling is maintained.

const parallaxBgImg = document.querySelector('#parallax-bg-img');

document.addEventListener('scroll', (event)=>{
  const rect = parallaxBgImg.getBoundingClientRect();

  if (rect.top < window.innerHeight) {
    const scrollableDistance = window.innerHeight + rect.height;
    const scrolled = window.innerHeight - rect.top;
    const percent = (scrolled / scrollableDistance) * 100;
    //don't go over 100% - can happen with elastic scroll on touch devices
    const finalPercent = Math.min(percent, 100);
    
    //Uncomment and use this instead for the opposite direction
    //parallaxBgImg.style.backgroundPositionY = `${finalPercent}%`;
    
    //Reversed direction
    const invertedPct = 100 - finalPercent;
    parallaxBgImg.style.backgroundPositionY = `${invertedPct}%`;
  }
});
body {
  background: gray;
  font-size: 140%
}

.content {
  margin: 50px auto 0px auto;
  max-width: 1100px;
  padding-bottom: 2000px;
  padding-top: 30px;
  background-color: white;
  border: solid black;
  border-width: 0px 16px 0px 16px;
}

.margin-content {
  margin: 30px 80px 0px 100px;
}

.header-img {
  width: 100%;
  background-image: url("https://i.stack.imgur.com/r6CD4.jpg");
  background-size: 150%;
  background-repeat: no-repeat;
  background-position: center;
}
<div class="content">
  <div class="margin-content">
    <h1> My Brand </h1>
  </div>
  <img src="https://i.stack.imgur.com/uxvh2.png" class="header-img" id="parallax-bg-img" />
  <div class="margin-content">
    <h2>Lorem ipsum dolor sit amet..</h2>
    <p>..consectetur adipiscing elit. Fusce ex erat, vehicula vitae sapien vel, dignissim ornare odio.</p>
  </div>
</div>
<!--</div>-->
<p style="color:white;text-align: center; position: relative; top:13px">© 2048 My Brand</p>

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

Methods for transferring data from an AJAX function

I have a database containing various links that I would like to retrieve and store within an array. I attempted to achieve this using the following code: var amz = new Array(); function CreateAmazonArray() { $.ajax({ url: "php/amazon_affilia ...

Implement a hover effect on a specific class targeting a nested element using JavaScript

Is there a method to apply a class that modifies rules for a child element using Javascript? I have successfully added it with CSS but am struggling to do the same with Javascript. Removing the class in JS is easy by referencing the classname before the ho ...

What is the correct way to set a function as the value for an object without using quotation marks?

I am facing a challenge of generating very large JavaScript files using Node.js. Each file contains a const variable that holds values tailored for the specific file, with these values only known at runtime. For example: 'use strict' const lib ...

reversed json using javascript

Is it possible to efficiently reverse the order of the following JSON object: { "10": "..." "11": "...", "12": "...", "13": "...", "14": "...", } so that it becomes: { "14": "...", "13": "...", "12": "...", "11": "... ...

Tips on when to display the "Email Confirmation" input text box only after updating the old email

Oh no!! Yes, that's exactly what I desire! I've been facing obstacles in trying to understand how to display the "Email Confirm" input text-box ONLY when the old email has been updated. Can someone point out where I might have gone wrong? :( ...

Can a font size be adjusted dynamically based on the width of its containing class?

I have encountered this issue before, but the previous solution did not work for me. I am now seeking a viable alternative. Currently, I am developing a website and have an event announcement block that needs to display the event date spanning the entire ...

creating dynamic parameterized URLs in Laravel

For example: Here are a few names. - Mujib - Amjed - Anees When someone clicks on "Mujib," the URL should remain the same and only the parameter should change. When someone clicks on "Amjed," the URL parameter should change to . ...

PageCallbacks in .NET 1.1

Is it possible to utilize PageMethods in .NET 1.1 for making server-side method calls from the client side? Could you provide a brief explanation on how to use this feature by calling PageMethods.MyMethod(); ? ...

Getting the WebElement object by manually clicking an element while in an active WebDriver Session

I am currently developing a Java Swing application for managing object repositories in Selenium scripts. This application will launch a WebDriver instance and allow users to manually navigate to the desired element for inspection. My goal is to capture th ...

Implementing a dynamic loading strategy for Google reCAPTCHA based on language selection

I have a unique application that requires the selection of one language out of four options (English, French, Dutch, español) in a form. Below the language selection, the Google reCaptcha is displayed. I am looking to dynamically load the reCaptcha scrip ...

Error encountered with structured array of objects in React Typescript

What is the reason for typescript warning me about this specific line of code? <TimeSlots hours={[{ dayIndex: 1, day: 'monday', }]}/> Can you please explain how I can define a type in JSX? ...

Troubleshooting collapsing problems in Bootstrap 5.2 using Webpack and JavaScript

I am currently developing a project utilizing HTML, SASS, and JS with Webpack 5.74.0. My goal is to implement a collapsible feature using Bootstrap 5, however, I ran into some issues while trying to make it work. To troubleshoot, I attempted to direct ...

Tips for maintaining the state in a React class component for the UI while navigating or refreshing the page

Is there a way to persist the selection stored in state even after page navigation? I have heard that using local storage is a possible solution, which is my preferred method. However, I have only found resources for implementing this in functional compone ...

What is the most efficient method for transforming an index into a column number that resembles that of Excel using a functional approach?

Is there a way to write a function that can produce the correct column name for a given number, like A for 1 or AA for 127? I know this question has been addressed numerous times before, however, I am interested in approaching it from a functional perspect ...

Laravel and x-editable team up to combat integrity constraint violation error code 1048, indicating no data being passed

Utilizing x-editable to generate an editable form that makes ajax requests. The form is structured as follows: <a href="#" class="editable editable-click" id="mileage" data-name="mileage" data-ty ...

Ways to receive attributes prior to the Render event

I am a beginner in React and encountering an issue with retrieving props from the parent before the child is rendered. https://i.sstatic.net/CLAdH.png My problem involves an Editor component that passes a string as props to a button. The string is collect ...

What is the best choice for my CSS: creating a block or an element using BEM methodology

** According to the official BEM website ** Create a block: If a section of code can be reused and does not rely on other page components being implemented. Create an element: If a section of code cannot be used separately without the parent entity (the ...

How can I pass an array object from an HTML form that adheres to a Mongoose schema

I have this HTML form that I'm using to create a new document in my mongo database. The document represents notes given to a teacher based on various criteria. I am storing the notes in an array within the note property, each object containing the aut ...

AngularJS Time Range Selector: A Slider Solution

I have successfully implemented a time range slider using Jquery and JqueryUI. $("#slider-range").slider({ range: true, min: 0, max: 1440, step: 15, values: [600, 720], slide: function (e, ui) { var hours1 = Math.floor(ui.values[0] / 60); var minu ...

Using multiple parameters in a GET request

url: "../api/api.php? fxn:" + encodeURIComponent(getCatergories) & "jsn"= +encodeURIComponent{"code":"1"}, var app = angular.module('MyTutorialApp',[]); app.controller("MainController", function($scope,$http){ $scope.loadpeople= functio ...