The transition of the element transform between the states of 'relative' and 'fixed' lacks smoothness

On my webpage, I have a banner element with the class .banner and a floating element with the class .float.

As the user scrolls, I want the floating element to appear centered vertically relative to the banner when it is in view. However, once the user scrolls past the banner, I want the floating element to stick to the screen.

Currently, the position of the floating element is always set to fixed, and I am utilizing Javascript to change the transform value in order to position it accordingly on scroll.

Although it is almost achieving the desired effect, I am struggling to make the element 'slide' smoothly between positions. When using a CSS transition, the element slides but when scrolling back up, it overshoots the vertical center of the banner. My goal is to have it seamlessly 'stick' to the banner once the user scrolls back up to it.

Any assistance would be greatly appreciated. For a visual representation, please refer to the following JSFiddle link: http://jsfiddle.net/L452xf7h/12/

HTML:

<div class="container">
  <div class="banner"></div>
  <div class="float">Floating Element</div>
</div>

CSS:

body, html {
  margin: 0;
}

.container {
  background: orange;
  height: 2000px;
}

.banner {
  width: 100%;
  height: 400px;
  background: white;
}

.float {
  display: none;
  width: 50px;
  height: 50px;
  background: red;
  position: fixed;
  top: 100px;
  right: 100px;
  /* this transition makes float travel high in banner when scrolling up */
  /* transition: transform .3s linear; */
}

JS:

var float = document.querySelector('.float');

if (float) {
    // init position
  onScroll();
  // check on scroll
  window.addEventListener('scroll', onScroll);
}

function onScroll() {
var banner_height = 400;
var float_topCss = 100;
var float_height = 50;
  if (window.scrollY < banner_height) {
    position = 0;
    // center vertically in banner
    position += banner_height / 2;
    position -= float_height / 2;
    // account for current scroll
    position -= window.scrollY;
    // minus difference of top css value
    position -= float_topCss;
    float.style.transform = "translate3d(0,"+position+"px,0)";
  }
  else {
    float.style.transform = "translate3d(0,0,0)";
  }
  float.style.display = 'block';
}

Answer №1

Is this the solution you seek?

    var scroll = document.querySelector('.scroll');

    if (scroll) {
   // initialize position
      onScroll();
      // check for scrolling
      window.addEventListener('scroll', onScroll);
    }

    function onScroll() {
    var banner_height = 400;
      if (window.scrollY < banner_height) {
        scroll.classList.remove('fixed');
      }
      else {
        scroll.classList.add('fixed');
      }
    }
    body, html {
      margin: 0;
    }

    .container {
      background: orange;
      height: 2000px;
      position: relative;
    }

    .banner {
      width: 100%;
      height: 400px;
      background: white;
    }

    .scroll {
      display: inline-block;
      width: 50px;
      height: 50px;
      background: red;
      position: absolute;
      top: 100px;
      right: 100px;
      float: right;
      transition: transform .3s linear;
    }

    .scroll.fixed {
      top: -50px;
      transform: translateY(150px);
      position: fixed;
    }
    
    <div class="container">
      <div class="banner"></div>
      <div class="scroll">Scrolling Element</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

Iterate through each element in all arrays, but limit the loop to only iterate through the elements in the first array up to its

Within my collection of arrays, each containing elements, the structure is as follows: var result = [ // starting with the outer array [ // initial internal array {name: 'A', value: 111}, {name: 'B', value: 222} ...

In MongoDB and Node.js, encountered error: 'Unable to access property 'collection' as it is undefined'

I'm encountering a type error with my collection function that was previously functioning without any issues. This code was working perfectly in another project of mine. After reusing a lot of the code, I started experiencing this error. My MongoDB c ...

Is using $timeout still considered the most efficient method for waiting on an Angular directive template to load?

When it comes to waiting for a directive's template to render, our team has been following the approach of enclosing our DOM manipulation code in a $timeout within the directive's link function. This method was commonly used in the past, but I&ap ...

Unable to override default styles with custom styles in React MUI 5

I've been attempting to replace the default MUI 5 Button styles with my custom styles using either withStyles or a className (created using makeStyles), but I'm running into an issue where the default styles take precedence over my custom ones. I ...

HTML animation effect on subpage with a URL modification [LATEST UPDATE]

Can you smoothly load a new subpage in the background, update the URL, and fade it in while an animation is playing on the previous page? Check out this example (jsFiddle) to see a simple animation: $(document).ready(function() { 'use strict&apo ...

Tips for increasing the size of a parent div when a child div is displayed with a set width?

Is there a way to make the parent div automatically expand when the child div with a fixed width is displayed onclick? Goal: I want the child div to show up when I click the link, and at the same time, I need the parent div to expand or scale to fit the ...

why is it that I am not achieving the expected results in certain areas of my work?

I am facing issues with getting an alert response from certain buttons in the code. The AC button, EQUALS button, and the button labeled "11" are not behaving as expected. I have tried troubleshooting but cannot identify the problem. Can someone please ass ...

What is the best way to pause the previous timer and display only the upcoming timer in a React application?

When comparing the scheduled times with the current date-time, I noticed that the values for upcoming schedule times are displayed correctly. However, when the time has already passed, it shows negative values. Instead of this, I would like to display &apo ...

What is the process for creating a multi-word argument?

Is there a way to create multi-word arguments, such as reasons for bans or mutes? Currently, I am using args[2], args[3], args[4], args[5]... but this approach is limited and if nothing is written in those arguments, it will display "undefined". If you k ...

Customize the delete icon margin styles in Material-UI Chip component

Currently, I have implemented the V4 MUI Chip component with a small size and outlined variant, complete with a specified deleteIcon. However, I am encountering difficulties when attempting to override the margin-right property of the deleteIcon due to MUI ...

Dealing with cascading jQuery deferred callsHere are some guidelines on

When I have a function that needs to retrieve data and return a promise, I often find myself making multiple requests one after another. This results in nested deffered calls where the last call resolves on the deferred object that the function ultimatel ...

Issue identified: Multer is unable to read the path property of req.file as it is undefined

I recently started working with node.js and wanted to create a simple REST Api with the ability to upload files. I decided to use multer from npm for file uploading and POSTMAN to send post requests. However, I encountered an error when trying to upload a ...

Stylish curved bottom border

Is it feasible to create this footer using just CSS? https://i.sstatic.net/b33w4.png Appreciate the help! ...

Errors are not being shown on mandatory fields in the form

After watching a tutorial video, I attempted to create a sign-up form. However, despite following all the steps, I encountered an issue where the Surname and Given name fields, which I set as required fields, were still processing blank when the form was s ...

Server has sent an Ajax response which needs to be inserted into a div

I have a modal window that sends a POST request to the server. Before returning to the view, I store some information in ViewData. Here's an example of what I'm doing: ViewData["Msg"] = "<div id=\"msgResponse\" class=\"success ...

Create a self-bot that can generate a new server

I am currently working on a discord.js self-bot and I need assistance in creating a server. Any guidance would be greatly appreciated. I have experimented with the client.user method, but did not achieve the desired result. If it is not possible to c ...

Is it possible to write CSS 3 rows without using the :not() selector for improved efficiency?

Consider using CSS code like the following in some cases: input:not([type="submit"]):not([type="checkbox"]):not([type="radio"]):not([type="file"]) { border:1px solid #fff; background-color:#f3f4f5; } <div><input type="text" name="alpha" /&g ...

Tips for transferring data to the next page with JavaScript AJAX

I am working on a webpage that includes an html select element <pre> $query = mysql_query("select * from results"); echo "<select id='date' onchange='showdata()' class='form-control'>"; while ($arr = mysql_fetch_a ...

"message": "Please provide a valid user path.",

When attempting to store the user in the database, the response indicates that the "user" path is required even though the user value is present in req.body and logged for verification purposes. However, the issue persists with storing it in the database. ...

How can I set the input tag to reset back to 1 when a certain event occurs?

I am currently developing an HTML Snakes And Ladders game. On the settings screen, there is an input field where users can select the size of the board. Depending on their choice, they will be able to choose a maximum number of snakes and ladders. For exa ...