Creating a visually engaging parallax effect in two columns with differing lengths that align perfectly at the conclusion

Recently, I came across an interesting layout technique on Apple's website that involves two columns with different lengths. As you scroll down the page, one column slows down to align with the other so that they both meet at the bottom.

You can check out this effect on Apple's macOS High Sierra Preview.

I attempted to recreate this layout using JavaScript and CSS on JSFiddle here. The columns behave as expected, stopping scrolling when their bottoms match.

$(window).scroll(function() {
  var marginvariant = $(window).scrollTop() * (($('#left').height() / $('#right').height()) * 0.16);
  marginvariant = Math.round(marginvariant);
  var $left = $('#left');
  var leftbottom = $('#left').height() - $left.position().top - marginvariant;
  var $right = $('#right');
  var rightbottom = $('#right').height() - $right.position().top;
  var bottomdif = leftbottom - rightbottom;
  if (bottomdif >= 0) {
    $('#left').css('margin-top', -marginvariant);
  }
});

However, I am facing a challenge in initiating the parallax effect only when the columns reach the top of the page, rather than immediately upon scrolling. I have experimented with various solutions to detect this but encountered issues with object offsets. Additionally, I aim to dynamically calculate the multiplier for smoother right column scrolling based on page and column heights to ensure they align perfectly at the end.

Answer №1

I am absolutely fascinated by the design on the MacOS High Sierra website. If you're interested, I've come up with a partial solution that I've shared on my codepen. Feel free to take a look and provide some feedback!

$(window).on("load resize scroll",function(e){
var col1 = $("#left").outerHeight();
var col2 = $("#right").outerHeight();
var travel = col1 - col2;

var topOfColumns = $('.parallax').offset().top;
var columns = $('.parallax').outerHeight() - $(window).innerHeight();
var scrollInterval = columns / travel;

    var e = Math.round( ($(window).scrollTop() - topOfColumns ) / scrollInterval);
    //find the bottom of the right column and give a Bool (true)
    var b = $(window).scrollTop() >= $('#right').offset().top + $('#right').outerHeight() - window.innerHeight;

    //if the user scrolls to the top of the columns and the user has not scrolled to the bottom of the right column
    if ($(window).scrollTop() >= topOfColumns && b == false ) {
        $("#right").css({
            "-webkit-transform": "translate3d(0px, " + e + "px, 0px)",
               "-moz-transform": "translate3d(0px, " + e + "px, 0px)",
                "-ms-transform": "translate3d(0px, " + e + "px, 0px)",
                 "-o-transform": "translate3d(0px, " + e + "px, 0px)",
                      transform: "translate3d(0px, " + e + "px, 0px)"
        });
    }
});

Answer №2

Have you attempted using a method similar to the one outlined in this https://medium.com/explore/detecting-element-visibility-with-jquery-6388cbb69061 article to determine when an element is within the viewport? I've been experimenting with creating a similar effect involving 2 columns, but haven't quite figured out the solution... and tutorials seem scarce. Have you had any success achieving this?

Answer №3

After experimenting with the provided code, I attempted to trigger the parallax effect when the anchor (represented by the red line in the image) reaches the top of the window using an anchor ID. While the method was somewhat successful, it resulted in a noticeable jump in the left column once the anchor point was reached, as depicted in the attached image.

Below is the code snippet used:

var anchor_offset = $('#anchor').offset().top;

$(window).on('scroll', function() {
  var marginvariant = $(window).scrollTop() * (($('#left').height() / $('#right').height()) * 0.16);
  marginvariant = Math.round(marginvariant);
  var $left = $('#left');
  var leftbottom = $('#left').height() - $left.position().top - marginvariant;
  var $right = $('#right');
  var rightbottom = $('#right').height() - $right.position().top;
  var bottomdif = leftbottom - rightbottom;

  if ($(window).scrollTop() > anchor_offset && bottomdif >= 0) {
    $('#left').css('margin-top', -marginvariant);
  }
});

View the image showing the anchor jump issue

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

What is the proper location to insert CSS within Laravel?

What is the recommended location for storing CSS or JS files in Laravel? More specifically, what are the differences between placing CSS files in /public versus /resources/css? Which directory is preferable for storing my CSS files? ...

Send the selected option from the dropdown menu to a different page

I am in the process of designing a unique shopping cart system where, upon clicking on the "add to cart" link, both the selected quantity from the drop-down menu and the product ID are transmitted to the addCart page. While I have successfully managed to p ...

Ensuring IconButton is perfectly aligned with Text in one straight line

I want to display IconButtons alongside plain text in a single block of text, but the result didn't turn out as I had hoped. Here is what I attempted: JS(ReactJS): <div> <span> <h3>Title</h3> <IconButton className ...

Enhancing Symfony's performance through optimized Ajax response time

When using Symfony2, I am experiencing differences in loading times for AJAX requests between development and production environments. In development, it takes 1 second to load, while in production it only takes 500 milliseconds for a simple call: Here is ...

Tips for reconnecting tinymce to a textarea following an ajax refresh

Whenever I submit a form with a tinymce textarea, the containing div gets reloaded using the following code: $('body').on('submit', '.comment_form', function (e) { e.preventDefault(); tinyMCE.triggerSave(); ...

``Advanced Web Development: Dealing with HTML5, CSS3, and

I am facing an issue while implementing a design from the CSS and HTML login form templates on my project. Below is the snippet of my HTML: <p id="firstname_line"> <label>First Name:</label> <input type="text" name="firstnam ...

Error message: "No elements were found in Ember.js jQuery cycle slideshow"

As I transition a traditional HTML site to an Ember.js application, I encountered a problem with the jQuery Cycle slideshow plugin. With approximately 10 slideshows on the site, I aimed to create a reusable partial to pass data to. Although the data passi ...

Incorporating PHP script within a stylesheet

Is it possible to include php code within a css file for adding conditions to css properties? styles.css <?php if($suserid == 2) { ?> .proverb { border:0px solid blue; margin-left:34px; width:250px !important; margin-top:6px; } <?php } e ...

hint.css guide for inserting line breaks into hints

Is there a way to manually insert line breaks in Hint.css hints? I've attempted using <br>, \n,, and various combinations of them. I've also experimented with the following CSS properties: white-space: normal; word-wrap: break-word; ...

html pagination on website

I am currently displaying my products in rows, however the code I'm using is presenting them in columns instead. I have implemented a datatable pagination feature, but I'm struggling to understand how to properly use it on my website. Can someone ...

Refresh the Datatable with the click of a button

Despite my efforts and multiple attempts at different solutions, I am unable to get this particular issue resolved. It seems that my lack of experience with javascript/UI is hindering me from achieving the desired outcome. The background function in quest ...

seeking a solution to simulate a variety of web browsers

Seeking a solution to preview my website on various browsers including IE7 and above, as well as different versions of Firefox. Although I am new to CSS, I previously tried installing software on my PC to assist with this task, which unfortunately caused ...

Problem with Raphael Sketch and Request to Ajax

Utilizing Raphael.js and jQuery Ajax, I am attempting to display some dots (circles) on the map in this [Demo][1]. I have a PHP file called econo.php which looks like this: <?PHP include 'conconfig.php'; $con = new mysqli(DB_HOST,DB_USER,DB_P ...

Unable to trigger the (click) event when adding new data in ANGULAR 4

Whenever I attempt to add the "tr tag", the (click) event is not functioning in Angular 4. Below is my code snippet. $('#time_table_table tbody').append('<tr data-id="1"><td>Sunday<a (click)="assign(1)">Assign</a>< ...

Ways to organize the information within the Ul and Li elements

I need help sorting the data within <ul> and <li> elements using jQuery. Below is a snippet of my code: <ul id="rootUl"> <li> <div id='title'>MSFT</div> <div id='price'>230</d ...

Ensuring validation with Javascript upon submitting a form

Hey there, I'm looking to validate field values before submitting a form. Here's the code I have: <table width="600" border="0" align="left"> <tr> <script type="text/javascript"> function previewPrint() { var RegNumber = docum ...

What could be the reason for this tag showing up empty after being parsed with beautiful soup?

Currently utilizing beautiful soup to parse through this particular page: In an effort to retrieve the total revenue for 27/09/2014 (42,123,000) which is among the primary values at the top of the statement. Upon examining the element in chrome tools, it ...

How to Handle the Absence of HTML5 Spellcheck in Specific Web Browsers

While HTML5 spellcheck functionality may vary across different browsers, there are instances where it might not be supported in certain corporate environments. In the event that HTML5 is not supported in a particular browser, it's essential to first c ...

Columns in Bootstrap4 housing elements positioned absolutely

Recently, I've been developing a game that involves using absolute positioning for certain elements. This is necessary for creating moving animations where elements need to slide around and overlap to achieve a specific effect. As I focus on optimizi ...

Responsive design is achieved through the use of CSS media queries targeting the

Could someone please clarify the meaning of the following value? Does it indicate that the output device must support exactly 256 colors, or is it acceptable for the output device to have 256 colors or fewer, or does the device need to support 256 colors ...