Mobile Safari bug on fixed positioned button after scrollTop programmatically changed...? Mobile Safari bug on fixed positioned button after scrollTop programmatically changed...? jquery jquery

Mobile Safari bug on fixed positioned button after scrollTop programmatically changed...?


We also encountered this bug on 2 different iPad applications, for us the best fix was to temporarily remove the fixed position from the fixed element once the animated scroll had finished, then use window.scroll with the vertical value we’d just performed the animated scroll to, then finally re-apply the position fixed style. It does cause a very minor blip as the ipad re-renders the element but its preferable to the bug.

var $fixedElement = $('#fixedNavigation');var topScrollTarget = 300;$("html:not(:animated),body:not(:animated)").stop().animate({ scrollTop: topScrollTarget }, 500, "swing", function(evt) {    $fixedElement.css({ "position": "relative" });    window.scroll(0, topScrollTarget );    $fixedElement.css({ "position": "fixed" });});


I got around it by adding a 101% high div then (almost) immediately removing it.

Try:

<style>.iosfix {  height: 101%;  overflow: hidden;}</style>

and when you scroll:

window.scrollTo(0, _NEW_SCROLLTOP_);$('body').append($('<div></div>').addClass('iosfix'));setTimeout(function() {  $('.iosfix').remove();}, 500);

It also works with jQuery.scrollTo.

See an example here.


I had multiple links on separate fixed elements (a modal popup + fixed blackout div + normal fixed toolbar) and none of these answers were working so I had a tinker about trying variations on the same theme. Like all these suggest the key is getting elements re-rendered.

Initially I tried adding 1px to the width of fixed elements and removing it. This did cause re-rendering, but re-rendered elements became mis-aligned with non re-rendered elements - another result of this iOS bug I suspect. The answer was to simply add to the width of the body and subtract again (or set to auto), ie:

//jQuery will calculate the current width and then +1 to this and set it$('body').css('width', '+=1');//Remove width csssetTimeout(function() {  $('body').css('width', '');}, 1);

If not using jquery you will need to get the current width of body +1px to it and then set the width.