I have run in to a problem that effects specifically Safari on iOS.
I am building a page which has a fixed position header that is the width of the viewport. The content of the page is a series of images (variable in number) which should scroll to the right. The header should remain in place when the user scrolls.
On iOS Safari, the fixed header, is slightly larger than the viewport, and also scrolls at a different speed than the rest of the content.
I've cut the code down to the following, and still cannot work out how to solve this problem - the following code works perfectly in all other browsers that I have tested. (I am targeting IE8+)
I've hosted the example of this problem here.
Thanks for any advice and help.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>test</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="viewport" content="initial-scale=1.0, maximum-scale=1.0, user-scalable=no"/>
<style>
html {
font-size: 10px;
height:100%;
white-space: nowrap;
}
body {
height:100%;
padding:0;
margin:0;
}
#dgs2 {
height:75%;
display:inline-block;
}
img{
height: 100%;
}
#pad{
height:6em;
padding-bottom:1px;
}
#header{
position:fixed;
width:100%;
height:6em;
border-bottom:1px solid;
}
.menuRight{
float:right;
}
</style>
</head>
<body>
<div id="header">
<div class="menuRight"><h2>Menu</h2></div>
<h1>Testing scroll on iPhone</h1>
</div>
<div id="pad"></div>
<div id="dgs2">
<img src='img/red.png'/><img src='img/blue.png'/><img src='img/red.png'/><img src='img/blue.png'/><img src='img/red.png'/><img src='img/blue.png'/><img src='img/red.png'/><img src='img/blue.png'/>
</div>
</body>
</html>
I know this question is a year old at this point, but the issue still exists in iOS and I had the EXACT same issue with fixed elements drifting, and it was driving me nuts. The answer is pretty simple: Just wrap the div #bgs2 (or whatever element has "white-space:nowrap" on it) with div.wrapper (the class is unimportant obviously), and set the overflow to auto:
.wrapper {
overflow: auto;
-webkit-overflow-scrolling: touch;
}
I also added webkit-overflow-scrolling, which helps with avoiding repaints.
Someone in the future is bound to find this bizarre issue, so hopefully it helps.
If your happy using jQuery, then you could use something like:
$(window).ready(function() {
var bodyWidth = $(window).width();
$("#header").width(bodyWidth).css('width', bodyWidth);
});
I included both the attribute width and the css width, just to be sure it works in all browsers. Also if you change your meta tag to:
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
That should also help.
Update 1
Sorry, I didn't read the CSS styles properly for the header. The styles for the header should be as follows:
#header{
position:fixed;
top: 0; // Set these positioning attributes
left: 0; // to hold the header in the top left.
width:100%;
height:6em;
border-bottom:1px solid;
}
Update 2
Again, another CSS update. I notice you have code like follows:
html {
font-size: 10px;
height:100%;
white-space: nowrap;
}
body {
height:100%;
padding:0;
margin:0;
}
#dgs2 {
height:75%;
display:inline-block;
}
You need to change it to read like the following:
html {
font-size: 10px;
height:100%;
}
body {
height:100%;
padding:0;
margin:0;
}
#dgs2 {
height:75%;
display:inline-block;
white-space: nowrap;
}
If you move the white-space: nowrap;
to the #dsg2
div instead of assigning it to the html
then this should be your final fix. Also, add the following to the jQuery code to accompany what you have already:
$(window).resize(function() {
var bodyWidth = $(window).width();
$("#header").width(bodyWidth).css('width', bodyWidth);
});