Categories:

A word on mobile devices and parallax scrolling

Parallax scrolling faces a few hurdles on mobile devices, some bigger than others. Starting with the obvious, due to mobile device's significantly smaller screen sizes, default images used in a parallax effect targeting desktops will often be too large in their smaller counterparts, both in terms of dimensions and file size. This can easily be addressed with CSS Media Queries. Continuing on with where we last left off with our parallax scrolling demo, lets add some CSS that supplants the original images with smaller versions in devices with width 860px or less:

Demo: Simple parallax scrolling effect

CSS:

/* Original CSS here... */

/* #### CSS media queries. Smaller versions of bg images for small screen devices #### */

@media screen and (max-device-width: 860px){

body{
background-image: url(deepsea_small.jpg);
}

#bubbles1{
background-image: url(bubbles1_small.png);
}

#bubbles2{
background-image: url(bubbles3_small.png);
}

#fish{
background-image: url(fish_small.png);
}

}

In a smaller tablet or smart phone, the browser will bypass downloading the original, gargantuan images and adopt the smaller images specified above instead. That in itself leads to a much more optimized, efficient experience for mobile users.

Parallax scrolling and iOS devices

Remember the tidbit at the very beginning about hurdles and "magnitude"? Well, this is the section it was alluding to. Parallax scrolling works relatively pain free in Android devices, albeit a little choppy as Android stutters to a certain degree the execution of code defined inside any onscroll event to conserve battery life. In iOS devices like on a iPad or iPhone, this conservation effort is taken to new heights. You see, in iOS devices, the onscroll event doesn't fire at all as the user scrolls, only at the end when the scrolling has ceased. Any queries/changes to the DOM you make as the user scrolls are queued and only honoured all at once at the end of the scrolling. This makes for some seriously choppy parallax scrolling as you can see if you view the parallax page on an iPad/ iPhone.

With parallaxing scrolling behaving badly in mobile devices, an easy way out is just to disable the effect in those devices. The following function can be used to detect mobile devices in general

var ismobile = /Android|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)
if (ismobile){
 // bypass parallax effect
}

Or to single out iOS devices, use the following detection instead:

var isiOS = /iPhone|iPad|iPod/i.test(navigator.userAgent)
if (isiOS){
 // bypass parallax effect
}

As our final tweak to our parallax demo, we will disable the parallax effect in iOS devices by conditionally executing the onscroll and onresize events inside the script:

<script>

var isiOS = /iPhone|iPad|iPod/i.test(navigator.userAgent)

"
"
if (!isiOS){
 window.addEventListener('scroll', function(){ // on page scroll
  requestAnimationFrame(parallaxbubbles) // call parallaxbubbles() on next available screen paint
 }, false)

 window.addEventListener('resize', function(){ // on window resize
  var scrolltop = window.pageYOffset // get number of pixels document has scrolled vertically
  var scrollamount = (scrolltop / (scrollheight-windowheight)) * 100 // get amount scrolled (in %)
  fish.style.left = -100 + scrollamount + '%' // set position of fish in percentage (starts at -100%)
 }, false)
}
</script>

Demo: Simple parallax scrolling effect

You may even choose to hide some of the layers such as the bubbles in iOS, instead of just disabling the effect.

Getting parallax scrolling to work in iOS devices

As mentioned, parallax scrolling isn't impossible in iOS devices, just aggravating to implement and not without compromises. In a nutshell, since iOS queues DOM changes defined inside the onscroll event until the scrolling has ended before executing them, we need a more refined way to execute our parallax code. One solution is to implement a custom scroll mechanism instead of relying on the default scrollbar to scroll the page, so we can monitor precisely when scrolling has occurred and by how much each time. This can be done by first wrapping any parallax elements inside a DIV with overflow:hidden, then moving this DIV and elements inside it up and down programmically as the user "scrolls" the page, using CSS3 transform for example. And to determine how much the user has scrolled without relying on the scrollbar, we use touch events instead. A working example of this can be seen here.

So as you can see, parallax scrolling in iOS is technically possible, but not without forking over some of the hair on your head first.