Fixed positioning is broken on iOS5/iOS6/iOS7.
Edit 3: See link to a working fix near end of this answer for iOS8.
Position:fixed is broken when either:
a) the page is zoomed
or
b) the keyboard shows on the iPad/iPhone (due to an input getting focus).
You can view the bugs yourself in jsbin.com/icibaz/3 by opening the link and zooming, or giving the input focus. You can edit the edit the html yourself.
Notes about bugs (a) and (b):
A fixed div with top: 0px; left: 0px;
will show in the wrong position (above or below the top of the screen) when an input gets focus and the keyboard shows.
The problem seems to have something to do with the auto-centering of the input on the screen (changing window.pageYOffset).
It appears to be a calculation fault, and not a redraw fault: if you force the top:
to change (e.g. switching between 0px and 1px) on the onScroll event, you can see the fixed div move by a pixel, but it remains in the wrong place.
One solution I used previously is to hide the fixed div when an input gets focus - see the other Answer I wrote.
The fixed div seems to becomes stuck at the same absolute position on the page it was at at the time when the keyboard opened.
So perhaps change the div to absolute positioning when an input has focus? Edit 3: see comment at bottom using this solution. Or perhaps save the pageXOffset/pageYOffset values before the keyboard is opened, and in an onScroll event calculate the difference between those values and the current pageXOffset/pageYOffset values (current once the keyboard is opened), and offset the fixed div by that difference.
There appears to be a different problem with fixed positioning if the page is zoomed - try it here (Also good information here about Android support for fixed in comments).
Edit 1: To reproduce use jsbin (not jsfiddle) and use the fullscreen view of jsbin (not the edit page). Avoid jsfiddle (and edit view of jsbin) because they put the code inside an iframe which causes interference with fixed positioning and pageYOffset.
Edit 2: iOS 6 and iOS 7 Mobile Safari position:fixed;
still has the same issues - presumably they are by design!.
Edit 3: A working solution for (b) is when the input get focus, change the header to absolute positioning and then set the header top on the page scroll event for example. This solution:
- Uses fixed positioning when input not focused (using window.onscroll has terrible jitter).
- Don't allow pinch-zoom (avoid bug (a) above).
- Uses absolute positioning and window.pageYOffset once an input gets focus (so header is correctly positioned).
- If scrolled while input has focus, set style.top to equal pageYOffset (header will jitter somewhat due to onscroll event delay even on iOS8).
- If using UIWebView within an App on iOS8, or using <=iOS7, if scrolling when input has focus, header will be super jittery because onscroll is not fired till scroll finishes.
- Go back to fixed position header once input loses focus (Example uses input.onblur, but probably tider to use
document.body.onfocus).
- Beware usability fail that if header too large, the input can be occluded/covered.
- I couldn't get to work for a footer due to bugs in iOS page/viewport height when the keyboard is showing.
- Edit example using http://jsbin.com/xujofoze/4/edit and view using http://output.jsbin.com/xujofoze/4/quiet
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…