locomotive-scroll
locomotive-scroll copied to clipboard
Footer/bottom cut off
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
I've the same problem
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.
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.
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 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
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() });
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(); });
@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.
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(); });
nothing works for me :(
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);
Here is the full Solutions For Footer Bottom Cut Off
- 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;
}
- 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();
});
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
- On local not live
- Using a 5s delay before calling scroll.update()
- 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 Did you already find a solution?
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.
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 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 fixed my comment, I added html tags by accident.
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 }); });
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
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();
});
},
}
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!
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() });
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!
Hey @TubeStorm Are you using GSAP?
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:
Hey @webmaster817 Iām not using GSAP. any solutions without it š
You can use Vanilla JavaScript instead.
@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 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;
}
});