We\'re seeing issues with a web app that has a height of 100% on Safari in iOS 7. It appears that the window.innerHeight (672px) doesn\'t match window.outerHeight (692px), b
A variant of Samuel's approach, but with position: -webkit-sticky set on html worked for me the best.
@media (orientation:landscape) {
html.ipad.ios7 {
position: -webkit-sticky;
top: 0;
width: 100%;
height: 672px !important;
}
}
Notice 'top: 0', not 'bottom: 0', and target element is 'html', not 'body'
You need JavaScript to work around this bug. window.innerHeight
has the correct height. Here's the simplest solution I can think of:
$(function() {
function fixHeightOnIOS7() {
var fixedHeight = Math.min(
$(window).height(), // This is smaller on Desktop
window.innerHeight || Infinity // This is smaller on iOS7
);
$('body').height(fixedHeight);
}
$(window).on('resize orientationchange', fixHeightOnIOS7);
fixHeightOnIOS7();
});
You'll also need to set position: fixed
on the <body>
.
Here's a complete, working example:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<meta name="apple-mobile-web-app-capable" content="yes"/>
<title>iOS7 height bug fix</title>
<script src="http://code.jquery.com/jquery-1.10.1.min.js"></script>
<script>
$(function() {
function fixHeightOnIOS7() {
var fixedHeight = Math.min(
$(window).height(),
window.innerHeight || Infinity
);
$('body').height(fixedHeight);
}
$(window).on('resize orientationchange', fixHeightOnIOS7);
fixHeightOnIOS7();
// Generate content
var contentHTML = $('#content').html();
for (var i = 0; i < 8; i++) contentHTML += contentHTML;
$('#content').html(contentHTML);
});
</script>
<style>
html,
body
{
margin: 0;
padding: 0;
height: 100%;
width: 100%;
overflow: auto;
position: fixed;
}
#page-wrapper
{
height: 100%;
position: relative;
background: #aaa;
}
#header,
#footer
{
position: absolute;
width: 100%;
height: 30px;
background-color: #666;
color: #fff;
}
#footer
{
bottom: 0;
}
#content
{
position: absolute;
width: 100%;
top: 30px;
bottom: 30px;
overflow: auto;
-webkit-overflow-scrolling: touch;
}
</style>
</head>
<body>
<div id="page-wrapper">
<div id="header">Header</div>
<div id="content">
<p>Lorem ipsum dolor sit amet.</p>
</div>
<div id="footer">Footer</div>
</div>
</body>
</html>
Simple, cleaner CSS-Only solution:
html {
height: 100%;
position: fixed;
width: 100%;
}
iOS 7 seems to set the height correctly with this. Also there is no need for resize javascript events, etc. Since you are working with a full height app, it doesn't really matter if it is always position fixed.
In my case, the solution was to change positioning to fixed:
@media (orientation:landscape) {
html.ipad.ios7 > body {
position: fixed;
bottom: 0;
width:100%;
height: 672px !important;
}
}
I also used a script to detect iPad with iOS 7:
if (navigator.userAgent.match(/iPad;.*CPU.*OS 7_\d/i)) {
$('html').addClass('ipad ios7');
}
I used this JavaScript solution for solving that problem:
if (navigator.userAgent.match(/iPad;.*CPU.*OS 7_\d/i) && window.innerHeight != document.documentElement.clientHeight) {
var fixViewportHeight = function() {
document.documentElement.style.height = window.innerHeight + "px";
if (document.body.scrollTop !== 0) {
window.scrollTo(0, 0);
}
}.bind(this);
window.addEventListener("scroll", fixViewportHeight, false);
window.addEventListener("orientationchange", fixViewportHeight, false);
fixViewportHeight();
document.body.style.webkitTransform = "translate3d(0,0,0)";
}
Samuel's answer is the best although it breaks if a user adds the page to their home screen (home screen pages don't exhibit the bug). Check the innerHeight before adding the class like so:
if (navigator.userAgent.match(/iPad;.*CPU.*OS 7_\d/i)) {
if(window.innerHeight==672){
$('html').addClass('ipad ios7');
}
}
Note that the bug also does not exhibit under webview.