Is there a way to achieve a parallax effect without relying on a background-image?

I am attempting to achieve a parallax effect without relying on background-image or background-attachment: fixed, as the latter doesn't function well on iOS. Below is my approach:

HTML

<article class="twentyseventeen-panel">
  <div class="panel-image">
    <div style="position: absolute; top: 0; bottom: 0; left: 0; right: 0;" >
      <img src="<?php echo esc_url( $thumbnail[0] ); ?>" style="width: 100%;" />
    </div>
  </div>
</article>

CSS

.twentyseventeen-panel {
    overflow: hidden;
    position: relative;
}
.panel-image {
    position: relative;
    height: 100vh;
    max-height: 200px;
}

I am currently facing a challenge with making the image scroll for the desired parallax effect. I have experimented with setting the image to a fixed position, but it causes the image to disappear. What would be the correct approach to implement a parallax effect in this scenario?

Answer №1

Regrettably, I am not aware of a foolproof method using only CSS. The challenge lies in the inability to access the current scroll position, which is necessary for a calc() function. Additionally, when positioning an element with fixed, it disregards its parent's constraints and prevents enforcing overflow:hidden.

There are two alternative approaches to creating a parallax effect without relying on background images—we can either utilize JavaScript, as demonstrated by the provided functional example, or optimize the code to apply the effect selectively on visible elements to avoid excessive browser processing.

$(document).ready(function() {
  var onScroll = function() {
    var scrollTop = $(this).scrollTop();
    $('.parallax-image').each(function(index, elem) {
      var $elem = $(elem);
      $elem.find('img').css('top', scrollTop - $elem.offset().top);
    });
  };
  onScroll.apply(window);
  $(window).on('scroll', onScroll);
});
.content {
  height: 500px;
}

.parallax-image {
  overflow: hidden;
  height: 200px;
  position: relative;
}

.parallax-image img {
  position: absolute;
  height: 100vh;
  min-width:100%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="content">
  <h2>Lorem Ipsum</h2>
  <div class="parallax-image">
    <img src="https://via.placeholder.com/400x200">
  </div>


</div>

In terms of implementing the full CSS solution, it can be quite intricate and may not be applicable to all layouts. The concept involves utilizing images with a position:fixed property at the lowest z-index level, designing cutouts within other elements' backgrounds to reveal the parallax image. While this technique presents challenges with background addition and necessitates multiple elements, I have simplified the demonstration to showcase the approach. This methodology supports a single image display; for multiple images, JavaScript functionality would be required to manage visibility transitions smoothly.

/* Can't use margins no more... */

h1 {
  margin: 0;
  padding: 0.67em 0;
}

p {
  margin: 0;
  padding: 1em 0 0;
}

body {
  margin: 0;
}

.container>* {
  background-color: white;
}

.parallaxed {
  z-index: -2;
  height: 100vh;
  position: fixed;
  top: 0;
}

.parallax-image {
  background: transparent;
  height: 200px;
}
<div class="container">
  <img class="parallaxed" src="https://via.placeholder.com/400x200">
  <h1>My Title here</h1>
  <div class="parallax-image"></div>
  <p>
    lorem ipsum...
  </p>
  <p>
    lorem ipsum...
  </p>
  <p>
    lorem ipsum...
  </p>
  <p>
    lorem ipsum...
  </p>
  <p>
    lorem ipsum...
  </p>
</div>

Answer №2

If you're looking to create CSS parallax effects without relying on background-image or background-attachment, there's a neat approach worth exploring. Keith Clark has penned an insightful article and tutorial on this very subject, which serves as a valuable resource for understanding the mechanics.

HTML Structure

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

CSS Implementation

.parallax {
  perspective: 1px;
  height: 100vh;
  overflow-x: hidden;
  overflow-y: auto;
}
.parallax__layer {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
}
.parallax__layer--base {
  transform: translateZ(0);
}
.parallax__layer--back {
  transform: translateZ(-1px) scale(2);
}

The key to achieving the parallax effect lies in the line of code

transform: translateZ(-1px) scale(2)
. This manipulation along the z-axis dictates the speed at which the effect unfolds. By adjusting values like translateZ, you can fine-tune the experience.

It's crucial to understand how setting perspective influences the visual output. By maintaining a thoughtful balance between transform properties and container attributes like overflow-y: auto, you can seamlessly integrate parallax elements into your design without resorting to JavaScript.

For a practical demonstration, check out this sample demo showcasing a single div parallax effect. Feel free to explore additional examples in this extensive showcase.

This technique is not only effective but also cross-browser compatible, making it a reliable choice for various projects. Be sure to delve into Keith Clark's tutorial for comprehensive guidance on leveraging these CSS capabilities.

Answer №3

Here is a solution that has worked well for me:

https://github.com/deggenschwiler/jquery_parallax

You will need to include jQuery in the header of your page:

<html>
<head>
    <style>
      .parallax {
        height: 400px;
        width: 100%;
        background-image: url("SOMEBGIMAGE.jpg");
        background-position-y: 0%;
        background-repeat: no-repeat;
        background-size: cover;
      }
    </style>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>

    <script>
    $(window).scroll(function() {
          var y = 0;
          var scroll = $(window).scrollTop();
          var win = $(window).height()
          var height = $(".parallax").height();
          var offset = $(".parallax").offset().top;
          y = ((100 * scroll)/(height + win)) + ((100 * (win - offset))/(height + win));
          if (y > 100){y = 100;}
          else if (y < 0){y = 0;}
          var out = String(y) + "%";
          $(".parallax").css("background-position-y", out);
    });
    </script>
</head>
<body>
    <div class="parallax">
    </div>
</body>
</html>

Answer №4

Use a CSS workaround by adjusting the container-padding to match the height of the parallax (for example, 100vh), and then position the child element (parallax area) as fixed or absolute within it. Experiment with z-index values to create a smooth parallax scrolling effect. This method proved successful for my project :)

Answer №5

Although this question may be a bit outdated, there is now a solution available that I would like to share for those who are still seeking it. You can utilize the scroll() function in CSS to control animation timelines based on the scrollbar axis. While not universally supported by all browsers (refer to here), this function enables you to create a parallax effect as demonstrated below:

body {
            display: flex;
            justify-content: center;
            align-items: center;
            min-height: 200dvh;
        }

        .container {
            width: 100%;
            height: 200px;
            overflow: hidden;
            display: flex;
        }

        img {
            object-fit: cover;
            animation-name: img-up-down;
            animation-duration: 1ms;
            animation-direction: alternate;
            animation-timing-function: linear;
            animation-timeline: scroll(root);
            min-width: 100%;
        }

        @keyframes img-up-down {
            0% {
                object-position: bottom;
            }

            100% {
                object-position: top;
            }
        }
<body>
    <div class="container">
        <img src="https://images.squarespace-cdn.com/content/v1/52540926e4b0d49865bee20d/1473520260750-LO9DJ4REDZYHU25BDX25/London+portrait+photographer"
            alt="">
    </div>
</body>

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

Move the formatted text of a TFS work item description into a Word document

Does anyone know the process for importing a TFS Workitem into Word using .NET? I have been attempting to import a Workitem through the API, but the description is provided to me as an HTML string. Is there any way to retrieve a formatted string of the ...

How can I add animation to an HTML5 video using jQuery?

How can we add animation to an HTML5 video element? <div id="cont"> <video id="movie" width="320" height="240" preload controls> <source src="pr6.ogv" type='video/ogg; codecs="theora, vorbis"'> <source src="p ...

displaying the local path when a hyperlink to a different website is clicked

fetch(www.gnewsapi.com/news/someID).then(response => newsurl.href = JSON.stringify(data.articles[0].url) fetch('https://gnews.io/api/v3/search?q=platformer&token=642h462loljk').then(function (response) { return response.json(); }).th ...

the frame on the page is distorting

I am trying to implement a frame around my website that overlaps elements. desired appearance Although I created a styled div for the frame, it seems to have a bug and looks like this: current appearance Below is the React code I am using: class About ...

A error was encountered stating that the formValidation function is not defined when the HTML form element is submitted

Having trouble calling a function and receiving an error message. How can I resolve this issue? The error message reads: index.html?email=&gebruikersnaam=&wachtwoord=&submit=Submit:1 Uncaught ReferenceError: formValidation is not defined at HT ...

Guide to Repairing Uncaught TypeError: players.setAttribute is not a recognized method?

I'm a beginner and encountered an error saying Uncaught TypeError: players.setAttribute is not a function when submitting an action. How can I solve this issue? Please share your insights. ''' //selecting all necessary elements const s ...

How to center a label vertically within a button group using Bootstrap

How can I vertically align labels for 2 inline elements inside a horizontal form without using hacks like display:table? So far, this is the code I have tried: bootply ...

What is the process for transforming information from a database into a clickable hyperlink?

My course list includes the following: SE1111 SE2222 SE3333 I want to display this list on my webpage and have it redirect to a page where the course name is saved for future use. Here's what I've tried so far: <div id="join_courses" clas ...

Sliding background in a multi-column accordion

I've hit a roadblock with this project. I'm working on setting up a FAQ section that needs to display its items in two columns on desktop, each with a drop shadow effect using Bootstrap 4. I've experimented with Flexbox and CSS columns with ...

Creating a Web Form in Outlook Using the POST Method

Seeking help in creating an HTML email featuring two interactive buttons - Approve and Reject. I have successfully generated the HTML email and sent it to Outlook. Snapshot: https://i.sstatic.net/NrGFM.png The HTML code within the email: <!DOCTYPE ...

Styling Rules for WebKit Browsers

Is there a method to apply a particular CSS style for a div based on whether the user is accessing the page from a Chrome browser on a Desktop or an Android device? .myDIV{ [if CHROME???] width: 280px; [if ANDROID???] width: 100%; } Seeking guidance on ...

`Carousel nested within tabbed interface`

I am currently facing an issue with my website's tabs and carousels. I have 4 tabs, each containing a carousel, but only the carousel in the first tab seems to be working properly. When I activate the second tab, all the carousel divs collapse. For r ...

Setting up only two input fields side by side in an Angular Form

I'm fairly new to Angular development and currently working on creating a registration form. I need the form to have two columns in a row, with fields like Firstname and Lastname in one row, followed by Phone, Email, Password, and Confirm Password in ...

What is the best way to align an image to the left side of the screen using Bootstrap 4?

I want to create a unique login page using bootstrap. My goal is to have an image on the left side and a form on the right side of the page. I need it to be responsive so that the image will disappear on smaller screens to prevent distortion. However, I a ...

Combining arrays that run parallel in Jquery

Seeking a solution similar to looping through multiple arrays in parallel using jQuery, but this time to construct an HTML page. I have three sets of parallel objects with arrays, potentially forming a 2D array. {"images":["Bellevue\/images\/1. ...

View's list fails to reflect changes in the Model

My goal is to create a MVVM architecture using knockout.js. The script within $(document).ready(function() {...} is supposed to add a new item model.addElement("value"); - "value" to the model every 3 seconds and display it in HTML. Despite seeing changes ...

Is there a way to place a button in the top-right corner next to my Bootstrap 5 card?

Can someone help me figure out how to position a button on the top right corner next to my bootstrap card? Here's the code I have so far: <div className="row p-5 m-2"> {savedEpisodes?.map((saved) => { return ( ...

Creating a bespoke scrollbar using Material UI

What is the best way to implement a custom scrollbar in Material UI? I have spent a lot of time researching how to add a custom scrollbar and I finally found a solution that works. Thanks to everyone who helped me along the way. ...

Unexplained vanishing of CSS padding upon form submission

Hey there! I've been working on creating a contact form using PhP, HTML, and CSS. Everything seems to be working fine except for one issue - when I submit the form with incorrect information, the CSS padding disappears. Can anyone help me figure out w ...

svg rect mistakenly appearing as a rounded polygon

I found a cool SVG pie chart on this codepen that I want to modify. The original chart is 50 x 50 and animated, but I want to make it 20 x 20. To resize the pie chart, I tried changing the width, height, radius, and center points in the code. I also adjus ...