Achieve a parallax effect with background images while scrolling, all without relying on the

Is there a way to achieve a parallax effect on an image without using the css background and background-attachment properties?

I have an img tag nested inside a div and I want to implement a parallax scroll effect on the image. Here is the code snippet:

function resize_div()
{
    var image_height = $('.project-image img').height();

    var div_height = $('.project-image').height();
    var window_height = $(window).height();
    var window_width = $(window).width();

   
        $('.project-image').css('height', window_height - 80);
    
}

$(window).resize(function () {
        resize_div();
});
.project-details
{
  width:100%;
}
.project-image{
  text-align:center
}
.project-description
{
  line-height:15px;
  margin:0 0 10px
}
.img-responsive
{
  height: auto;
  max-width: 100%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="project-details">
  <div class="project-image">
   <img src="http://placehold.it/350X225" class="img-responsive">
  </div>  
  <h1>
  Project Title
  </h1>
  <p class="project-description">
  Lorem Ipsum is simply dummy text of the printing and typesetting industry... (continued)

issue: The image cannot be placed in the background of a div, so it must be done using the img tag only.

Update: The image is centered horizontally within the div, and both the image and the div sizes are adjusted when the browser is resized or the device is rotated using custom JavaScript. Attempts with position:absolute and position:fixed have not been successful.

https://i.sstatic.net/2WUzE.jpg

Update-2: Check out the fiddle link for more details.

Answer №1

Not long ago, I created a couple of examples showcasing a parallax effect that closely resembles what you're interested in achieving:

  • this demonstration utilizes simple jQuery to update the image and title position as you scroll
  • this sample relies solely on CSS with 3D positioning to simulate the parallax effect on the image

I believe you don't necessarily need JavaScript to resize the image upon loading. Here's an example incorporating your code along with the jQuery snippet from the first pen I shared:

$( document ).ready(function() {
var $window = $(window);
function scroll_elements(){
  var scroll = $window.scrollTop();
  var scrollLayer = scroll/1.4;
  
  $(".project-image").css(
    "-webkit-transform","translate3d(0," +  scrollLayer  + "px,0)",
            "transform","translate3d(0," +  scrollLayer  + "px,0)"
  );
}

$window.scroll(scroll_elements);
});
.project-image {
  position:relative;
  z-index:1;
}
.img-responsive {
  display:block;
  max-width:100%; 
  height:auto;
  margin:0 auto;
}
h1, .project-description {
  position:relative;
  max-width:500px;
  z-index:2;
  background:rgba(255,255,255,.7);
  margin:0 auto;
  padding:10px 20px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="project-details">
  <div class="project-image">
   <img src="http://placehold.it/350X225" class="img-responsive">
  </div>  
  <h1>
  Project Title
  </h1>
  <p class="project-description">
  Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.
  <br/>
  <br/>
  Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.
  <br/>
  <br/>
  Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.
  </p>
</div>

Answer №2

After experimenting a bit, I have found what seems to be the most effective solution in this scenario:

*{
  margin: 0;
  padding: 0;
}

#image {
  width: 100%;
  position: fixed;
}

#image2 {
  width: 100%;
  position: relative;
  visibility:hidden;
}
#prl {
  position: relative;
  background-color: white;
}
  <img src="http://placehold.it/350X225" id="image">
  <img src="http://placehold.it/350X225" id="image2">

<div id="prl">
  <p>
  sdf sfkdl ksda klsadsdf sfkdl ksda klsadsdf sfkdl ksda klsadsdf sfkdl ksda klsadsdf sfkdl...

In this approach, no JavaScript is required as I am utilizing the same image twice - once for the fixed disappearing effect and once simply to reserve empty space.

Answer №3

Through my exploration, I stumbled upon this hidden gem.

$('.img-parallax').each(function(){
  var img = $(this);
  var imgParent = $(this).parent();
  function parallaxImg () {
    var speed = img.data('speed');
    var imgY = imgParent.offset().top;
    var winY = $(this).scrollTop();
    var winH = $(this).height();
    var parentH = imgParent.innerHeight();


    // The next pixel to show on screen      
    var winBottom = winY + winH;

    // If block is shown on screen
    if (winBottom > imgY && winY < imgY + parentH) {
      // Number of pixels shown after block appear
      var imgBottom = ((winBottom - imgY) * speed);
      // Max number of pixels until block disappear
      var imgTop = winH + parentH;
      // Porcentage between start showing until disappearing
      var imgPercent = ((imgBottom / imgTop) * 100) + (50 - (speed * 50));
    }
    img.css({
      top: imgPercent + '%',
      transform: 'translate(-50%, -' + imgPercent + '%)'
    });
  }
  $(document).on({
    scroll: function () {
      parallaxImg();
    }, ready: function () {
      parallaxImg();
    }
  });
});
@import url(https://fonts.googleapis.com/css?family=Amatic+SC:400,700);
html, body{
  margin: 0;
  padding: 0;
  height: 100%;
  width: 100%;
  font-family: 'Amatic SC', cursive;
}
.block{
  width: 100%;
  height: 100%;
  position: relative;
  overflow: hidden;
  font-size: 16px;
}
.block h2{
  position: relative;
  display: block;
  text-align: center;
  margin: 0;
  top: 50%;
  transform: translateY(-50%);
  font-size: 10vw;
  color: white;
  font-weight: 400;
}
.img-parallax {
  width: 100vmax;
  z-index: -1;
  position: absolute;
  top: 0;
  left: 50%;
  transform: translate(-50%,0);
  pointer-events: none
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="block">
  <img src="https://unsplash.it/1920/1920/?image=1005" data-speed="-1" class="img-parallax">
  <h2>Parallax Speed -1</h2>
</div>
<div class="block">
  <img src="https://unsplash.it/1920/1920/?image=1067" data-speed="1" class="img-parallax">
  <h2>Parallax Speed 1</h2>
</div>
<div class="block">
  <img src="https://unsplash.it/1920/1920/?gravity=center" data-speed="-0.25" class="img-parallax">
  <h2>Parallax Speed -0.25</h2>
</div>
<div class="block">
  <img src="https://unsplash.it/1920/1920/?image=1080" data-speed="0.25" class="img-parallax">
  <h2>Parallax Speed 0.25</h2>
</div>
<div class="block">
  <img src="https://unsplash.it/1920/1920/?random" data-speed="-0.75" class="img-parallax">
  <h2>Parallax Speed -0.75</h2>
</div>
<div class="block">
  <img src="https://unsplash.it/1920/1920/?blur" data-speed="0.75" class="img-parallax">
  <h2>Parallax Speed 0.75</h2>
</div>

Answer №4

After receiving approval from Nishant Solanki, this sample code is guaranteed to function seamlessly across all browsers.

function myFunction() {
speed = 0; 
  speed2 = -1;
  /**
  @ speed
  positive: moves up faster than background
  0: scrolls same as background
  negative: moves down faster
  -1: same as position: fixed
  try different ones to see it in action and you should figure it out
  
  P.S.
  you can apply different speeds to multiple alements to achieve what ever you desire
  */
y = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop || 0;
  cont = document.getElementById("prl");
  cont.style.top = (0 - Math.round(y * speed)) +"px";
  img = document.getElementById("image");
  img.style.top = (0 - Math.round(y * speed2)) +"px";
}
*{
  margin: 0;
  padding: 0;
}

#image {
  width: 100%;
  position: relative;
}
#prl {
  position: relative;
  background-color: white;
}
<body onscroll="myFunction()">

  <img src="http://placehold.it/350X225" id="image">

<div id="prl">
  <p>
  sdf sfkdl ksda klsadsdf sfkdl ksda klsadsdf sfkdl ksda klsadsdf sfkdl ksda klsadsdf sfkdl ksda klsadsdf sfkdl ksda klsadsdf sfkdl ksda klsadsdf sfkdl ksda klsadsdf sfkdl ksda klsadsdf sfkdl ksda klsadsdf sfkdl ksda...

Answer №5

Is it possible to utilize a straightforward approach like $(window).scroll to detect window scroll, and then easily apply .addClass, .removeClass, or .toggleClass? By adding new styles to the element with scrolling, you can proceed to adjust the position of your img.

$(document).ready(function(){
    $(window).scroll(function(){
        $('img').toggleClass('scrolled'); 
    })
})

.scrolled { 
  position: absolute;
  z-index: 777; // determine correct value
  top: 102px; // customize as needed
  left: 3px; // adjust based on requirements
}

Note:// A cleaner practice would be to achieve this effect using a background image and adjusting its position with .scroll. If you can refactor some code to implement this method, it may be beneficial in the long run. Alternatively, you can employ jQuery .scroll and .toggleClass while modifying the z-index: and position: properties. For responsive layouts, CSS3 is recommended; if the position: property isn't functioning correctly, there might be a conflict stemming from excessive CSS or JS affecting the relevant elements.

Answer №6

Using CSS, it's best to steer clear of both fixed and absolute positioning. Embrace the freedom it brings.

function myFunction() {
  fixIt = document.getElementById('project-image');
  fixIt.style.top = 2 * Math.round(document.body.scrollTop) + "px";
}
* {
  margin: 0;
  padding: 0;
}

#project-image {
  width: 100%;
  position: relative;
}

.project-description,
.project-details>h1 {
  position: relative;
  z-index: 1;
  background: white;
}

.project-details {
  overflow: hidden
}
<body onscroll="myFunction()">


  <div class="project-details">
    <div id="project-image">
      <img src="http://placehold.it/350X225" class="img-responsive">
    </div>
    <h1>
      Project Title
    </h1>
    <p class="project-description">
      Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has
      survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop
      publishing software like Aldus PageMaker including versions of Lorem Ipsum.
      <br/>
      <br/> Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen
      book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently
      with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.
      <br/>
      <br/> Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen
      book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently
      with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.
    </p>
  </div>
</body>

This modern plugin holds a special place in my heart. Check it out here

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

Signal for a complete 360 degree rotation of an image

Looking to enhance my 360 image rotator with an indicator that fades out after the first image. I added this function to the end of my 360.js: (function(){ if( $('#first').css('visibility','hidden')) { $('#rotat ...

Page Built with Bootstrap Showing Excessive White Space Below and Footer Misaligned

Looking for some assistance with a webpage I've been working on. Here is the page in question: I used the official static navbar example from Bootstrap as inspiration: https://getbootstrap.com/examples/navbar-static-top/ As well as the official stic ...

Monitoring page reload with JavaScript

Here is an example of tabbed content: <div class="tab"> <button class="tablinks" onclick="openCity(event, 'NewYork')" id="defaultOpen">New York</button> <button class="tablinks" onclick="openCity(event, 'LosAngeles& ...

I am struggling to implement the grid layout for my dashboard design in Tailwind CSS

Currently, I am in the process of developing a dashboard front-end utilizing Tailwind CSS. The grid structure has been established on the page, and various components have been integrated into it. However, there seems to be an issue with the uniformity of ...

Text positioned beneath a toggle switch in html that overlaps

Is there a way to fix the issue of the label on the left side overlapping below the selector switch on my website? I want to ensure that both labels are perfectly distributed on each side of the switch. Here is the code snippet: <div class="ro ...

What is the method for printing background images/styles without adjusting the browser's page setup?

Is there a method to maintain row striping in the printout like it appears on screen? <div id="test" style="background:#000000; color:#FFFFFF">Black Stripe</div> I would like to create a page with consistent row stripe formatting for printing ...

Revealing a concealed element by sliding it upwards on a single page, then repeating the

Can someone assist me in achieving a specific effect on my website? I have a top banner section with a button at the bottom. When the button is clicked, a form should slide up into view. The form will initially be hidden. I also need the same effect at the ...

The width of the PrimeNG p-password component does not align properly with the container size

Currently, I am working on designing a login page using Primeng. Everything seems to be functioning properly except for the p-password component which is not aligning correctly with the input above it. <div class="flex flex-column align-items-cente ...

Transform Array into an unordered list with list items

Currently, I am dealing with a file that contains strings of file paths in the following format: ./CatDV/S1/SFX/steam/6004_90_04 LargeHeadlightSm.wav ./CatDV/S1/SFX/steam/AirHissPressureRe HIT032001.wav ./CatDV/S1/SFX/steam/Impact_Metal_Bullet_Hit(1).wav ...

Guide on converting a JSON containing nested JSONs into an HTML table

Currently, I am working with a JSON data structure that contains nested dictionaries. My goal is to create an HTML table where each top-level key serves as a column in the table. The inner key-value pairs should be represented as a single text within cells ...

Exploring the tab-content features of Bootsrap 5 through anchor tags

In the previous version of Bootstrap, the tab-pane used to fade in active. However, in the new version, it is now: tab-pane fade show active. What other improvements can I make? <!DOCTYPE html> <html lang="en"> <head> <m ...

Can AJAX Delete requests be executed without using jQuery?

Is it possible to use AJAX delete request without using jQuery? My JSON object at localhost:8000 appears like this: { "Students":[{"Name":"Kaushal","Roll_No":30,"Percentage":94.5}, {"Name":"Rohit","Roll_No":31,"Percentage":93.5}, {"Name":"Kumar ...

Getting the hang of revealing a div through flashing

Is it possible to make a div flash using CSS alone? My goal is to have this div alternate between two colors. .chat-window .msg-container-base .notification-message-unread{ float: right; font-size: 10px; color: #666; background: white; padding ...

Tips for controlling the size of a canvas element: setting minimum and maximum width and height properties

function convertImageResolution(img) { var canvas = document.createElement("canvas"); if (img.width * img.height < 921600) { // Less than 480p canvas.width = 1920; canvas.height = 1080; } else if (img.width * img.he ...

Can someone guide me on how to make an array filled with dates using Javascript?

I am working on developing a Javascript code that can identify all the days leading up to the current date. Here is what I have managed so far: var titleArray = [ "title1", "title2", ]; var pictureArray = today.toString(); var thumbArray = today.toString ...

div consistently positioned above fixed element

My goal is straightforward - I have a fixed div at the bottom of my page that always needs to be visible. Inside this div, there are two sub-divs; one small div should always be on top, and the other should be scrollable. The issue lies with the small div ...

Empty the localStorage when terminating the IE process using the Task Manager

Utilizing HTML5 localStorage to keep track of my application session has been a useful feature. Here is a snippet of the code I am currently using: if(typeof(Storage)!=="undefined") { if(sessionStorage.lastname=="Smith") { alert("Your ses ...

Exploring the World of Print CSS, Embracing Bootstrap, and Master

In continuation of my previous query, I am facing an issue with setting up a filemaker foreach loop to display a group of images along with their names and IDs, accompanied by checkboxes. Upon checking the relevant checkboxes, the corresponding images are ...

Is it possible to trigger a submit button to perform a POST request and an AJAX call simultaneously

I have a form that sends a POST request to show_aht2.php, but I also need it to trigger an AJAX call as shown in the code below. How can I achieve this without redirecting the user to another page? I want the user to remain on map.php. Thank you in advanc ...

What is the process for including the title attribute in DNN controls within the DotNetNuke platform?

Is there a way to add the title attribute to the DNN:Label control and have it render as a title attribute, <label title="myTitle">, in HTML? My code snippet: <div class="dnnFormItem"> <dnn:label id="lblDateNeeded" runat="server" control ...