Insight

This is our blog; our space to share articles, news, and previews of our exciting projects

alex's picture

Single page layouts on mobile

Position:fixed solutions

Single page layouts are a really clean approach for brochure style websites, and all it takes is jQuery scrollTo() and a position:fixed navigational element to have a sleek looking face-page. Oh wait, whats that mobile webkit? You don’t do position fixed. Awesome.

Mobile browsers (or at least ones that use the mobile webkit) handle the window/document/viewing screen differently than a desktop browser. A good breakdown of exactly what is going on can be found here. So basically position:fixed on mobile means just that, fixed to the ENTIRE document window, not the view window.... so what can we do?

One could go for complex approach like iScroll, jQuery mobile, Sencha or this guys’ proof-of-concept, but in this case we just wanted something simple that looks nice on mobile. I found a little javascript/position:absolute combo in a comment on stack overflow for emulating position:fixed behavior in a position:absolute element:

window.onscroll = function() {
  document.getElementById('fixedDiv').style.top =
     (window.pageYOffset + window.innerHeight - 25) + 'px';
};

Nice and simple. However iPhones and iPads don’t fire the onscroll event until the view port stops moving... which means your element is left hanging in the middle of the page (this also happens with scrollTo). The best (easy) solution is to hide your absolutely positioned navigational element while you’re scrolling. With scrollTo this is easy since they have an onAfter function built in:

$(‘#link’).click(function() {
  //Hide your navigation
  $.scrollTo( $(‘#target’), { onAfter:function(){
    //Show your navigation
  }}
});

For regular scrolling, there are some javascript event listeners for mobile touch devices. You can read more about them here, but for our purposes all we need to use is:

document.addEventListener('touchmove', function (e) {
  //Hide your navigation
}

Then we show the navigation again on the onscroll event!

window.onscroll = function() {
  //recalculate navigation position and show it
}

Some other useful things to think about here are your behaviors when window.resize() is fired (zooming) and also address orientation changes:

window.onorientationchange = function() {
    //Do something
}

And there you have it, some straight forward code to implement in your single page layout to ensure a smooth mobile experience.