locomotive-scroll icon indicating copy to clipboard operation
locomotive-scroll copied to clipboard

Footer/bottom cut off

Open Mishkamshka opened this issue 4 years ago ā€¢ 39 comments

Hi, I have a wordpress site, and I'm using GSAP, bootstrap & locomotive. 50% of the time when I refresh my page the footer is cut off, and when I resize the page it shows what was once hidden. What can I do to prevent this? I've used the standard GSAP locomotive code provided by GSAP and it's still not working. I'm also unsure how to add mobile smooth with the new update.

I'd really appreciate your help. Thank you

Mishkamshka avatar Jan 19 '21 21:01 Mishkamshka

I've the same problem

MatteoBruschetti avatar Jan 20 '21 15:01 MatteoBruschetti

This is a sign that LocomotiveScroll was initialized before the page was fully loaded. Basically, the height of the container is too small because it was computed, then some content was loaded afterward.

This can be due to:

  • Stylesheets
  • Fonts
  • Lazy loaded content

To fix it, you have to update() the scroll.

If you can listen for the elements listed above, you can simply trigger the update() when they are done rendering. If not, you can update() with a timeout (not a great solution, use this as a last resort, as it's very unreliable).


Also, if you have the intention of having anything impacting the height of the body (like collapsible), you'll need to call the update(), every time they finish their animations.

fcisio avatar Jan 21 '21 01:01 fcisio

Thanks @fcisio, I was looking for this kind of explanation. It would benefit this repository if the way height is computed was documented like you did.

p.s.: this issue is a duplicate of #209.

remi-lebigre avatar Jan 21 '21 08:01 remi-lebigre

Thank you @fcisio, my images are lazy loaded on wordpress by default. I'm sorry to ask, but how do I update()? I currently have ScrollTrigger.addEventListener("refresh", () => locoScroll.update()); But I tried wp_get_attachment_image.addEventListener("refresh", () => locoScroll.update()); But I don't know what I'm doing, and that doesn't work because "it's not defined"

Please help, I'm even willing to pay

Thank you

Mishkamshka avatar Jan 21 '21 20:01 Mishkamshka

@Mishkamshka lazyloading happens on the client-side. I don't know how the images are lazyloaded on your WordPress, but you would need to interact with the library that takes care of that.

If we take lazySizes for example, you could do something like:

document.addEventListener('lazyloaded', function(){
    locoScroll.update()
});

Furthermore, I would suggest that you change or extend the lazyloading behavior completely. When lazy loading images, there should be some aspect ratio styling in place to prevent jumps while they are loading. See article

fcisio avatar Jan 21 '21 21:01 fcisio

Thank you so much!! @fcisio

For those wondering I'm using GSAP on wordpress and this is the code I used ScrollTrigger.addEventListener('wp_lazy_loading_enabled', function(){ locoScroll.update() });

Mishkamshka avatar Jan 21 '21 22:01 Mishkamshka

You have to update locomotive scroll when all images are loaded

for detection of all image loaded or not you can use imagesloaded

here is code that work for me -

imagesLoaded(currentScrollContainer, { background: true }, function () { scroll.update(); });

Dushyant1295 avatar Jan 22 '21 17:01 Dushyant1295

@mishkamshka I had a similar problem. I was specifying data-scroll-section on some sections of the page but not others (for example the footer) - and the areas without data-scroll-section were disappearing. Adding data-scroll-section to those areas too fixed the issue for me.

tigerchick avatar Feb 27 '21 11:02 tigerchick

You can specify that if the big container ".locomotive-scroll" finishes loading its images, you can update locoScroll (since you'll be using .locomotive-scroll as your parent div you can target this container). This works for me and its seems better than the interval workaround.

imagesLoaded(".locomotive-scroll", { background: true }, function () {
locoScroll.update();
});

Referring from Dushyant1295's code.

You have to update locomotive scroll when all images are loaded

for detection of all image loaded or not you can use imagesloaded

here is code that work for me -

imagesLoaded(currentScrollContainer, { background: true }, function () { scroll.update(); });

richardvisuals avatar May 11 '21 04:05 richardvisuals

nothing works for me :(

prakash03yes avatar Jul 19 '21 12:07 prakash03yes

None of the solutions work for me either. I've tried waiting for the entire page to load and then create the instance. Even tried setting an arbitrary 5s timeout (local testing, not live), nothing works.

window.addEventListener("load", () => {
  const scroll = new LocomotiveScroll({
    el: document.querySelector("[data-scroll-container]"),
    smooth: true,
    multiplier: 0.75,
    scrollFromAnywhere: true,
  });
});
setTimeout(() => {
  scroll.update();
}, 5000);

theaswath avatar Jul 25 '21 06:07 theaswath

Here is the full Solutions For Footer Bottom Cut Off

  1. Calculate Height With CSS So You Don't have to wait for images to be loaded
<div class="wrapper"> 
        <img src="">
</div>

.wrapper {
    position: relative;
    height: 0;
    padding-bottom: 50%;
    /* šŸ‘† image height / width * 100%   (use this formula to calculate the height the image )    */
}
 .wrapper  img{
        width: 100%;
        height: auto;
        position: absolute;
    }
  1. You have to update locomotive scroll when all images are loaded for detection of all image loaded or not you can use imagesloaded
       var currentScrollContainer =  document.querySelector("[data-scroll-container]");
        imagesLoaded(currentScrollContainer, { background: true }, function () {
                   scroll.update();
        });

Dushyant1295 avatar Jul 25 '21 09:07 Dushyant1295

The above solution didn't work for me, but I also don't think its the problem with images. I can say that but because I'm

  1. On local not live
  2. Using a 5s delay before calling scroll.update()
  3. Removed all the images on the page yet the behavior is the same.

Also, the bottom portion of the footer being cutoff is different on different pages with varying amounts of text, page length and images. Hence I can't say that more or heavier images = more footer cut or longer the page the more is cut. Also, setting any amount of margin/padding on the footer element just results in more arbitrary cropping of bottom content. The amount of footer cropped seems arbitrary.

Another observation is this only occurs when smooth is set to true. Setting it to false ensures no part of the container is cut. So if the below code is used, nothing is cropped.

window.addEventListener("load", () => {
  const scroll = new LocomotiveScroll({
    el: document.querySelector(".wrapper"),
    smooth: false,
    multiplier: 0.75,
    scrollFromAnywhere: true,
  });
});

But then what's the point of using locomotive-scroll if there is no smooth scrolling šŸ˜….

This also appears to be related to #66.

Any suggestions on how I get any useful data of what is happening?

Edit: Extra information, JS code snippet added, added relation to previously closed issue.

theaswath avatar Jul 25 '21 14:07 theaswath

@theaswath Did you already find a solution?

alexanderverbeeck avatar Sep 17 '21 10:09 alexanderverbeeck

To me, this sounds like a CSS problem. You might have some margins that collapse in the container (which is the default).

Try adding display: flex; to your container, it will disable the margin collapsing.

Other than that, I really doubt it has anything to do with locomotive-scroll, but rather its implementation. Make sure that there isn't anything impacting the position of the container itself.

For example, if there is a margin-top on the container, the bottom of the page will be cut off because that margin basically offsets the whole container.

I would also suggest adding a button on the page that triggers scroll.update(), that way you can manually test it out.

āš ļø If your images are lazyloading, there is a big chance that the initial update after 5s is not doing much since the height of the content will still change as you scroll.

fcisio avatar Sep 17 '21 16:09 fcisio

Same issue: either I had too much whitespace under my scroll container or the footer would get cut off. None of the JS solutions made a difference and the issue persisted even without images or any type of lazy loaded elements on the page.

This worked for me:

  • have locomotive.css loaded, or alternatively make sure your html and body are set to overflow: hidden when .has-scroll-smooth is active.
  • instead of adding data-scroll-container to a page element, add it to the body element
  • the last data-scroll-section should be the footer. I'm not sure why but this seems to cut off the excess white space without removing the footer along with it.

I hope this saves someone the 4 hours that it took me to figure it out.

EvaBrarens avatar Sep 23 '21 14:09 EvaBrarens

@EvaBrarens What do you mean with '"instead of adding data-scroll-container to a page element, add it to the last data-scroll-section should be the . I'm not sure why but this seems to cut off the excess white space without removing the footer along with it."

alexanderverbeeck avatar Sep 27 '21 10:09 alexanderverbeeck

@alexanderverbeeck fixed my comment, I added html tags by accident.

EvaBrarens avatar Sep 27 '21 10:09 EvaBrarens

if using jquery, you can just set it on load such as below.

$(document).ready(function () { const scroller = new LocomotiveScroll({ el: document.querySelector('[data-scroll-container]'), smooth: true }); });

abw1996 avatar Mar 16 '22 02:03 abw1996

None of the solutions work for me either. I've tried waiting for the entire page to load and then create the instance. Even tried setting an arbitrary 5s timeout (local testing, not live), nothing works.

window.addEventListener("load", () => {
  const scroll = new LocomotiveScroll({
    el: document.querySelector("[data-scroll-container]"),
    smooth: true,
    multiplier: 0.75,
    scrollFromAnywhere: true,
  });
});
setTimeout(() => {
  scroll.update();
}, 5000);

It's worked for me. great solution

mhasan320 avatar Apr 26 '22 23:04 mhasan320

The imagesloaded method works for me. I use Nuxt.js & below is for reference :)

In terminal, run:

npm install imagesloaded

In your vue component/ page:

import imagesLoaded from "imagesloaded";
...
data(){
  return{
   scroll: null,
  };
},
mounted() {
   this.locomotiveScrollInit();
 },
beforeDestroy() {
   this.scroll.destroy();
 },
methods: {
  locomotiveScrollInit() {
        let scrollContainer = document.querySelector("[data-scroll-container]");
  
        this.scroll = new this.$LocomotiveScroll({
          el: scrollContainer,
          smooth: true,
          getDirection: true,
        });
  
        // to fix locomotive bug on setting up too early (img not yet loaded)
        imagesLoaded(scrollContainer, { background: true }, () => {
          this.scroll.update();
        });
  },
}

snowiewdev avatar Jun 19 '22 07:06 snowiewdev

None of the solutions work for me either. I've tried waiting for the entire page to load and then create the instance. Even tried setting an arbitrary 5s timeout (local testing, not live), nothing works.

window.addEventListener("load", () => {
  const scroll = new LocomotiveScroll({
    el: document.querySelector("[data-scroll-container]"),
    smooth: true,
    multiplier: 0.75,
    scrollFromAnywhere: true,
  });
});
setTimeout(() => {
  scroll.update();
}, 5000);

It's worked for me. great solution

it is working perfect for me, thank you!

tamoimi avatar Aug 20 '22 10:08 tamoimi

If you using locomotive-scroll with GSAP, please use it, it works for me.

ScrollTrigger.create({ trigger: "footer", start: "top bottom", end: "bottom top", once:true, onEnter: () => locoScroll.update() });

webmaster817 avatar Sep 21 '22 15:09 webmaster817

Hey any idea how to fix this, I have all my page content in a div, and I have a script in the html for the locomotive stuff. Not sure why but my page keeps clipping and I can't see the rest of it. If i resize my browser then I can see everything. It's been driving me crazy.

<div class="locomotive-scroll">
    content
</div>

<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/locomotive-scroll.css">
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/locomotive-scroll.min.js"></script>
<script>
	const locoScroll = new LocomotiveScroll({
		el: document.querySelector(".locomotive-scroll"),
		smooth: true,
		smartphone: {
				smooth: false
		},
		tablet: {
				smooth: false
		},
		smoothMobile: 0,
		multiplier: 1.0,
	}); 
		
</script>

None of the solutions work for me either. I've tried waiting for the entire page to load and then create the instance. Even tried setting an arbitrary 5s timeout (local testing, not live), nothing works.

window.addEventListener("load", () => {
  const scroll = new LocomotiveScroll({
    el: document.querySelector("[data-scroll-container]"),
    smooth: true,
    multiplier: 0.75,
    scrollFromAnywhere: true,
  });
});
setTimeout(() => {
  scroll.update();
}, 5000);

It's worked for me. great solution

it is working perfect for me, thank you!

TubeStorm avatar Sep 22 '22 07:09 TubeStorm

Hey @TubeStorm Are you using GSAP?

webmaster817 avatar Sep 22 '22 07:09 webmaster817

If so, please use above code I had wrote. And if possible, please divide code to div and footer.

Before, I had the same issue like you and it could be solved by using setTimeout()function, while duration is 5000. It worked well but if the content is too big, it would fail. At that time, I was using Locomotive-scroll with GSAP so I solved it using GSAP. I detected the moment when footer reaches bottom of browser (viewpoint), and then runs scroll.update(). It worked perfectly and client satisfied with this.

Followings are my code: Annotation 2022-09-22 164350

webmaster817 avatar Sep 22 '22 07:09 webmaster817

Hey @webmaster817 Iā€™m not using GSAP. any solutions without it šŸ˜­

TubeStorm avatar Sep 22 '22 07:09 TubeStorm

You can use Vanilla JavaScript instead. Annotation 2022-09-22 170349

webmaster817 avatar Sep 22 '22 08:09 webmaster817

@webmaster817 Not sure if I wrote this correctly. this is what i have. Still no luck. I have a fixed footer (that's always visible), but I have another section at the bottom of the page (a second footer), that keeps getting cut off. šŸ˜­šŸ˜­šŸ˜­

<!-- Locomotive Scroll -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/locomotive-scroll.css">
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/locomotive-scroll.min.js"></script>
<script>
	const locoScroll = new LocomotiveScroll({
		el: document.querySelector(".locomotive-scroll"),
		smooth: true,
		smartphone: {
				smooth: false
		},
		tablet: {
				smooth: false
		},
		smoothMobile: 0,
		multiplier: 1.0,
	}); 

	function isInViewport(el) {
		const rect = el.getBoundingClientRect();
		return(
			rect.top >= 0 &&
			rect.left >= 0 &&
			rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) &&
			rect.right <= (window.innerWidth || document.documentElement.clientWidth)
		);
	}

	const footer = document.querySelector(".footer");
	document.addEventListener('scroll', function() {
		if (isInViewport(footer))
			locoScroll.update();
	});

</script>

TubeStorm avatar Sep 23 '22 00:09 TubeStorm

@TubeStorm Or you can use locomotive-scroll call function instead. Please add data-scroll and data-scroll-id="second-footer" to second footer. Then add this code to JavaScript


<div class="second-footer" data-scroll data-scroll-id="second-footer">
......

var f_flag = true;
locoScroll.on('scroll', (args) => {
    if(typeof args.currentElements['second-footer'] === 'object' && f_flag == true) {
        locoScroll.update();
       f_flag = false;
    }
});

webmaster817 avatar Sep 23 '22 00:09 webmaster817