scottjehl / Device-Bugs

Just a collection of quirks and issues that occur on browser platforms (particularly those unlikely to update)
864 stars 19 forks source link

iOS 5 Position:fixed Element not repositioned correct after scrolling Page with JS #23

Open fwebdev opened 12 years ago

fwebdev commented 12 years ago

How to reproduce

I found two Ways to work around that Problem.

This one works for me now (jQuery style):

$('body, html')
    .animate({scrollTop: 0})
    .scrollTop(0);

Here is another solution that worked for me before (I guess) But that is not working for me anymore.

$('myNavi').css({'position': 'relative'});
window.scroll(0,1);
$('myNavi').css({'position': 'fixed'});
lucipacurar commented 12 years ago

I'm having the same issue on iOS 5 but I can't find a workaround. It says here that this is an mobile Safari bug: http://stackoverflow.com/questions/9145025/jquery-click-events-not-firing-on-positionabsolute-td-tag-on-ios-after-scroll

wasinsandiego commented 12 years ago

You could append to the body a div with height greater than body. This forces the browser to update whatever is necessary for the fixed position css to respond. This approach is vaguely mentioned by Zachary Johnson HERE along with a great example of this IOS bug. But I found using height: 101% did not work for me, so I wanted to share my implementation.

The example below appends and then removes a styled div. Simply call updateScollFixed() when you need it.

The javaScript:

var updateScrollFixed = function(){
    $("body").append('<div class="iosFixedFix"></div>');
    setTimeout(clearIOSFix, 1); 
}

var clearIOSFix = function(event){
    $(".iosFixedFix").remove();
}

The CSS:

.iosFixedFix{
    position: absolute;
    width: 100%;
    height: 10000px; /* This value must always be higher than the body height. */
    top: 0px;
    left: 0px;
}

The Implementation:

$(".fullScreenButton").on("click", function(event){
    openFullScreenOverlay();
    updateScrollFixed();
});

Using it after page load and after a scroll animation will help out too. However if you need it for something like a fixed nav menu that is visible all the time then this might not work for you. My guess is that calling updateScrollFixed() on an interval loop or scroll event would not perform well. You may need to explore another approach, but the concept is here and it worked well in a "full screen" overlay type of situation.

lucipacurar commented 12 years ago

As a workaround I'm using this HTML and CSS code:

<body>
<ul id="menu">
    <li><a href="#">Item 1</a></li>
    <li><a href="#">Item 2</a></li>
    <li><a href="#">Item 3</a></li>
</ul>
<div id="page_container">
    My content is here
</div>
</body>
body {
    height: 100%;
}

#page_container {
    bottom: 0;
    left: 0;
    overflow: auto;
    position: absolute;
    right: 0;
    top: 0;
}

#menu {
    position: fixed;
    top: 30px;
    left: 10px;
}

In this way I can scroll the content of the "page_container" div when clicking on one of the menu items.

nicam commented 12 years ago

thanks a lot for this :) @fwebdev's alternative method worked while the first one didn't

TheBlueMajestic commented 10 years ago

I have been experiencing a similar issue with a mobile app that I created. My situation involved placing my navigation bar within a scrollable element (i.e. my page). I placed the navigation block outside of the page block and now the navigation stays put when I scroll. No fancy CSS or JS required. Hope this helps someone in the future.