Is it possible to have the background scroll downward while keeping some content centered in place at all times?

Attempting to achieve the following effect in JavaScript, HTML, and Sass:

  • When scrolling down the page, the layers (ground, sky, space, etc.) move downward
  • The content (a rocket flying in the sky) stays centered on the screen and will move horizontally like it's flying
  • Some elements will move within the layers (e.g., asteroids moving from right to left)

Here are some code snippets I've tried, but they don't work as intended. The layers scroll correctly, but not all of them are visible. They seem to fill the entire page, which is not the desired behavior. I've searched online for solutions, but haven't found anyone who has done something similar.

// Functions
detectPageVerticalPosition = () => {
  pageVerticalPosition = pageYOffset;
};

getDivs = () => {
  for (
    let div = document.getElementsByTagName("div"), i = 0; i < div.length; i++
  ) {
    div[i].getAttribute("class") == "layer-vertical" &&
      layerVerticalArray.push(div[i]);
  }
  console.log("layerVerticalArray: ", layerVerticalArray);
};

moveLayers = () => {
  for (let i = 0; i < layerVerticalArray.length; i++) {
    layerVerticalArray[i].style.bottom = -1 * pageVerticalPosition + "px";
  }
};

// End Functions

// Variables
var pageVerticalPosition = 0,
  layerVerticalArray = new Array();
// End Variables

// Events
window.onload = e => {
  getDivs();
  // console.log(layerVerticalArray);
};

window.onscroll = e => {
  detectPageVerticalPosition();
  moveLayers();
};
// End Events
body {
  margin: 0;
}

#page {
  position: relative;
  height: 20000px;
  width: 100%;
}

#rocket-container {
  position: fixed;
  width: 100%;
  height: 100%;
  top: 0;
  left: 0;
}

#rocket-container #rocket {
  position: absolute;
  width: 100px;
  height: 100px;
  left: calc(50% - 50px);
  top: calc(50% - 50px);
}

#background-container {
  position: fixed;
  height: 100%;
  width: 100%;
  background-color: red;
  overflow: hidden;
}

#background-container .layer-vertical {
  width: 100%;
  height: 3500px;
}

#background-container #layer-vertical-1 {
  position: absolute;
  background-color: blue;
}

#background-container #layer-vertical-1 #cloud-1 {
  outline-style: dashed;
  right: 0px;
}

#background-container #layer-vertical-1 #cloud-2 {
  outline-style: dotted;
  bottom: 0px;
}

#background-container #layer-vertical-2 {
  background-color: green;
}

#background-container #layer-vertical-3 {
  background-color: purple;
}

.cloud {
  position: absolute;
  width: 180px;
  height: 120px;
  background-image: url(../images/cloud.png);
}
<div class="page">
  <div class="background-container">
    <div class="layer-vertical" id="layer-vertical-1">
      Layer 1
      <div class="cloud" id="cloud-1"></div>
      <div class="cloud" id="cloud-2"></div>
    </div>
    <div class="layer-vertical" id="layer-vertical-2">
      Layer 2
    </div>
    <div class="layer-vertical" id="layer-vertical-3">
      Layer 3
    </div>
  </div>
  <div id="rocket-container">
    <div id="rocket">STAY MIDDLE</div>
  </div>
</div>
[1]:

Answer №1

After some investigation, I came up with a solution to resolve this issue. You can view the implementation on this jsfiddle link: http://jsfiddle.net/kjrte2sd/2/

I utilized jQuery to ensure that the background-container scrolls down smoothly instead of individual elements scrolling independently. This approach eliminated the need for the page div and allowed the body to handle the resizing of the entire layout.

Surprisingly, the solution turned out to be simpler than I initially anticipated.

var winHeight = $(window).innerHeight();

$(document).ready(() => {
  $(".layer-vertical").height(winHeight);
  $("body").height(winHeight * $(".layer-vertical").length);
});

window.addEventListener("resize", e => {
  $(".layer-vertical").height($(window).innerHeight());
});

$(window).on("scroll", () => {
  $("#background-container").css("bottom", $(window).scrollTop() * -1);
});
body {
  margin: 0;
  padding: 0;
}

#rocket-container {
  position: fixed;
  width: 100%;
  height: 100%;
  top: 0;
  left: 0;
}

#rocket-container #rocket {
  position: absolute;
  width: 100px;
  height: 100px;
  left: calc(50% - 50px);
  top: calc(50% - 50px);
}

#background-container {
  position: fixed;
  bottom: 0;
  left: 0;
  width: 100%;
}

#background-container .layer-vertical {
  width: 100%;
}

#background-container .layer-vertical h1 {
  width: 100px;
  position: relative;
  display: block;
  margin: 0 auto;
  text-align: center;
  top: 50%;
}

#background-container #layer-vertical-1 {
  background-color: green;
}

#background-container #layer-vertical-2 {
  background-color: red;
}

#background-container #layer-vertical-3 {
  background-color: white;
}

#background-container #layer-vertical-4 {
  background-color: pink;
}

#background-container #layer-vertical-5 {
  background-color: yellow;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="background-container">
  <div class="layer-vertical" id="layer-vertical-5">
    <h1>5</h1>
  </div>
  <div class="layer-vertical" id="layer-vertical-4">
    <h1>4</h1>
  </div>
  <div class="layer-vertical" id="layer-vertical-3">
    <h1>3</h1>
  </div>
  <div class="layer-vertical" id="layer-vertical-2">
    <h1>2</h1>
  </div>
  <div class="layer-vertical" id="layer-vertical-1">
    <h1>1</h1>
  </div>
</div>

<div id="rocket-container">
  <div id="rocket">STAY MIDDLE</div>
</div>

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

Steps for creating a herringbone design on an HTML canvas

Seeking Help to Create Herringbone Pattern Filled with Images on Canvas I am a beginner in canvas 2d drawing and need assistance with drawing mixed tiles in a cross pattern (Herringbone). var canvas = this.__canvas = new fabric.Canvas('canvas' ...

Using React, update the checkbox so that it dynamically changes from checked to unchecked

Hey there, I'm currently working on a table that includes checkboxes. The idea is that when I click on "Add Entries", a modal opens up; and when I click on "Done", I want the checkboxes to become unchecked without having to refresh the page. Do you ha ...

The `background-size` property in jQuery is not functioning as expected

I am facing the following issue: When I click on a div with absolute positioning, I want to animate its position, width, and height. In addition, I want to change the background-size using jQuery. However, the problem is that all CSS properties are updat ...

Using jQuery to parse JSON transforms an array into a hash object

I recently encountered an issue with a string that I needed to convert into a JSON object. The string looked like this: string = '{ "key": [ { "foo": "bar" } ] }'; To convert the string, I used: json = $.parseJSON(string); However, after co ...

Interactive Div Updates Dropdown Selections Automatically

// function to add set of elements var ed = 1; function new_server() { ed++; var newDiv = $('#server div:first').clone(); newDiv.attr('id', ed); var delLink = '<a class="btn btn-danger" style="text-align:right;m ...

Refresh the page without reloading to update the value of a dynamically created object

Maybe this question seems silly (but remember, there are no stupid questions).. but here it goes. Let me explain what I'm working on: 1) The user logs into a page and the first thing that happens is that a list of objects from a MySQL database is fet ...

Prevent request timeouts in Express.js

I am currently experimenting with methods to terminate client requests that are prolonging excessively, thus depleting the server's resources. After reviewing various sources (referenced below), I attempted a solution similar to the one suggested here ...

Is using selectors a more effective way to retrieve computed data compared to using class methods?

When using react, redux, and reselect in a project, is it preferable to move all computable data from class methods to selectors and avoid mixing the use of both? Are there different concepts behind these approaches? class DocsListView { getOutdatedDocs ...

Error: AsyncPipe received an invalid argument of type '[object Object]'. This has caused an error due to an invalid pipe argument

I'm currently working on developing a contact management system that includes CRUD operations using Angular 8 and Spring Boot. Every feature is functioning correctly except for the search functionality. My goal is to search for data based on a specifi ...

SonarLint versus SonarTS: A Comparison of Code Quality Tools

I'm feeling pretty lost when it comes to understanding the difference between SonarLint and SonarTS. I've been using SonarLint in Visual Studio, but now my client wants me to switch to the SonarTS plugin. SonarLint is for analyzing overall pr ...

Tips for adjusting image size in Bootstrap carousel

Is it possible to change the width of the image in this carousel? How can I resize the image without affecting the red box? I've tried numerous solutions on various forums, but none seem to work. The image just won't shrink the way I want it to ...

Is there a way to adjust the timepicker value directly using the keyboard input?

Is there a way to control the material-ui-time-picker input using the keyboard instead of clicking on the clock? This is my current code: import React, { Component } from "react"; import { TimePicker } from "material-ui-time-picker"; import { Input as Ti ...

What is the best way to incorporate a custom margin within a grid system while ensuring it remains responsive?

I'm currently working on incorporating 4 non-bootstrap "cards" into my HTML layout, with some space between them. Here is an image depicting how it's supposed to look: https://i.sstatic.net/bppvW.png The problem arises when I attempt to make the ...

Solving Issues with URL Parameters and AJAX

My JSP page has a JavaScript function called loadData() that is triggered when the page loads. This function makes an AJAX request to a servlet in order to retrieve data and return the necessary HTML content to display on the page. I am trying to call thi ...

Update the image source through an AJAX call

I've experimented with various methods to update an image src using an AJAX request. The new URL is obtained through the AJAX call, and when inspecting the data in Developer Tools, the 'DATA' variable contains the correct URL. However, the i ...

Struggling with Nuxt 3 Firebase and VueFire: unable to get useCurrentUser to work

Currently, I am attempting to implement VueFire's useCurrentUser() function within a Nuxt 3 application that does not utilize Server Side Rendering. I have properly configured vuefire in my nuxt.config.ts file as outlined in the documentation. export ...

Move your cursor over the top and bottom of the image to experience distinct effects

Trying to create an effect where the top 50% of an image shows a different color and text when hovered over, and same for the bottom 50%. Currently, only able to achieve this effect for the lower half of the image. Is there a way to make it work for both h ...

Generate a JavaScript function on the fly

I am looking for a way to dynamically bind a function to the .click() event of multiple divs in a loop. Once clicked, the function should hide the respective div. Despite my attempts, I have been struggling with losing reference to the div and unsuccessful ...

What could be causing my THREE.js Documentation Box to malfunction?

I am a newcomer trying to get the hang of THREE.js. I delved into the THREE.js Documentation and attempted to implement the code, but when I loaded my HTML page, it appeared blank. I am at a loss for what to do next. I utilized Visual Studio Code for codin ...

Can someone explain the significance of this error message in Redux - Toolkit?

Encountered this error message while working with Redux-Toolkit, could someone explain its meaning? name:"ConditionError" message:"Aborted due to condition callback returning false." ...