I am having a problem with scrolling being choppy on Firefox mobile on Android.
I have found a solution (workaround) to my problem but I don't really like it and I would like someone to explain to me what causes it or point me in the general direction of the cause. So basically I would like to understand why it behaves the way it does. First I'll layout what I am trying to achieve and then give the workaround.
I am trying to do a CSS only parallax scroll effect without any Javascript at all, I know it is probably impossible given the differences in browsers. So please, no Javascript solutions, I know how to do it in Javascript, I would like only to see how far I can go in a CSS only approach.
I already have a working version of my code that you can see in action here https://nkalait.maseru.co.ls/home, scrolling on this page on Android is smooth with the Chrome and DuckDuckGo browsers but choppy with Firefox.
I'll also add that:
- I have tested with and without loading images so the issue seems to have nothing with images,
- I have tested with and without translate3d(0,0,0) or translateZ(0) and again the issue seems to have nothing that,
- I have tested with will-change, it seemed to help somewhat but not significantly,
- I have have traced most of the performance issue to the components showing 3 components showing details about mobile, web, and backend development (if you saw the page) so I completely removed these components and most of the jankyness went away but there was still some left, it still was not scrolling smoothly on Android Firefox
I'll now give the exact code but redacted(to make it easier to read) code I have. Note, this is a Vue.js build. App.vue is the root view and Home.vue is the view with content and is loaded directly in App.vue.
App.vue (the root):
<template>
<div id="app">
<Home />
</div>
</template>
<style lang="scss">
body,html {
margin: 0px;
padding: 0px;
width: 100vw;
height: 100vh;
}
body {
overflow: hidden;
}
#app {
overflow-x: hidden;
overflow-y: scroll;
width: 100vw;
height: 100vh;
perspective: 100px;
transform-style: preserve-3d;
scroll-behavior: smooth;
// ***FIX Option 1***
@supports ( -moz-appearance:none ){
@media (max-width: 768px) {
perspective: 0px;
}
}
}
</style>
Home.vue
<template>
<div class="home">
.
.
.
</div>
</template>
<style lang="scss" scoped>
.home {
transform-style: preserve-3d;
// ***FIX Option 2***
@supports ( -moz-appearance:none ){
@media (max-width: 768px) {
transform-style: initial;
}
}
transform: translate3d(0px, 0px, 0px) scale(1);
width: 100vw;
}
</style>
The Workaround
I have managed to trace the problem down to 2 places, in the code there is FIX Option 1 and FIX Option 2, either of these on it's own fixes the problem but of course means I take away the parallax effect on Firefox which is fine for now.
FIX Option 1: Reset perspective to 0px on the element where scrolling occurs thus taking aways its 3D-ness,
FIX Option 2: Reset transform-style to its initial state on the element with the content
Node: I have used FIX Option 1 on the live code so if you do go to the link you will not see the issue because I could not leave it as it was with a problem like that.
I understand what these 2 "fixes" do, or the theory at least, my request is to be helped to understand what exactly causes this in Android Firefox that is different in the other browsers and how to fix it IN A CSS ONLY APPROACH.
Testing Platform
Firefox version: Firefox 68.1.1,
Android version: 7.0,