Skip to content

Instantly share code, notes, and snippets.

@backflip
Last active December 12, 2015 05:29
Show Gist options
  • Save backflip/4722355 to your computer and use it in GitHub Desktop.
Save backflip/4722355 to your computer and use it in GitHub Desktop.
Issues with fixed header

FIXED HEADER ON MOBILE

Problem

Some platforms do not support a value of "fixed" for the CSS property "position", which is used to position elements relative to the viewport where they remain while scrolling. It is possible to emulate this behavior using CSS or JavaScript. However, there are several trade-offs:

  • It is not reliable to listen to the scroll event and re-position a fixed element while scrolling. One approach is to hide the fixed elements when scrolling starts and show them again when it stopped (jQuery Mobile was using this for some time).
  • The only somewhat working solution is to create a "scrollview" which is as tall as the viewport and to scroll inside this area instead.
  • A "scrollview" can either be created using CSS or JavaScript. The CSS solution (overflow:scroll) is not feasible because there is no scroll momentum, usually no scrollbars and many platforms require two fingers for scrolling. There is a new CSS property on webkit (-webkit-overflow-scrolling) which solves most of this problems. Unfortunately, it's only supported on iOS >= 5 and possibly some of the most recent Android versions, where it is of no use since they both support position:fixed anyway.
  • The JavaScript solutions listen to touch events and move elements around accordingly. They can emulate native characteristica like momentum, bouncing and scrollbars. Solutions like iScroll (http://cubiq.org/iscroll-4) work pretty good, however, they never really feel like native scrolling and potentially have a performance impact.
  • Those JavaScript solutions have a major drawback: detecting browser support for position:fixed is extremely unreliable. Therefore it is very difficult to use position:fixed on supported browsers and only fall back the JavaScript solution when necessary.

Recommendation

I suggest using position:fixed on platforms which support it (iOS >= 5, Android >= 2.1, current versions of other platforms, see http://caniuse.com/css-fixed) and do without a fixed header on other platforms.

Remark: Android 2.1. to 2.3 require a viewport meta tag with a value of "user-scalable=no" in order to support position fixed. This has major accessibility drawbacks (http://www.iheni.com/mobile-accessibility-tip-dont-suppress-pinch-zoom/) and is generally not recommended, however often used.

UPDATE: Old Android browsers (including the default one on our HTC with Android 4) do not support position:fixed when there is any element on the page which has a CSS transform property. Therefore, we cannot use iScroll (which relies on CSS transforms) in combination with a fixed header on this platform. So there is either no fixed header or a scrollview for the content.

Real-world examples

Websites

  • m.facebook.com: No fixed header
  • mobile.twitter.com: position:fixed (on iOS only)

Frameworks

  • Foundation: Only browsers supporting position:fixed.
  • jQuery Mobile: «Prior to version 1.1, jQuery Mobile used dynamically re-positioned toolbars for the fixed header effect because very few mobile browsers supported the position:fixed CSS property, and simulating fixed support through the use of "fake" JavaScript overflow-scrolling behavior would have reduced our browser support reach, in addition to feeling unnatural on certain platforms. This behavior was not ideal, and jQuery Mobile 1.1 took a new approach to fixed toolbars that allows much broader support. The framework now offers true fixed toolbars on many popular platforms, while gracefully degrading non-supporting platforms to static positioning.» (http://jquerymobile.com/demos/1.2.0/docs/toolbars/bars-fixed.html)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment