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.
- Creating a basic parallax scrolling effect using CSS and JavaScript
- A word on mobile devices and parallax scrolling