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';
}