Most mobile browsers, including the iPhone, implement a dynamic chrome hide that provides a valuable increase in content rendering area on small screens.
Many websites employ a JavaScript scrolling trick which triggers this process.
The hide occurs as soon as the scroll is executed, which itself is often delayed by a timeout to ensure a successful hide.
Without checks, this can be annoying. If we have scrolled manually the page still jumps back to the top :-/
This problem is especially prevalent on slower mobile device connections, the very devices upon which the trick is used.
The objective here is to implement an auto-scroll that doesn't annoy the user at all.
First, unsupported scenarios are excluded:
We abort if space saving measures that are normally coupled with chrome hiding are not employed and if the screen is large enough that fixed chrome is standard.
Next, scenarios where the scroll would be annoying or unlikely to do anything useful are excluded:
The following code demonstrates this decision making process.
// Hide address bar on devices like the iPhone
//---------------------------------------------
function hideAddressBar(bPad) {
// Big screen. Fixed chrome likely.
if(screen.width > 980 || screen.height > 980) return;
// Standalone (full screen webapp) mode
if(window.navigator.standalone === true) return;
// Page zoom or vertical scrollbars
if(window.innerWidth !== document.documentElement.clientWidth) {
// Sometimes one pixel too much. Compensate.
if((window.innerWidth - 1) !== document.documentElement.clientWidth) return;
}
setTimeout(function() {
// Already scrolled?
if(window.pageYOffset !== 0) return;
// Perform autoscroll
window.scrollTo(0, 1);
// Reset body height and scroll
if(bodyTag !== undefined) bodyTag.style.height = window.innerHeight + 'px';
window.scrollTo(0, 0);
}, 1000);
}
In situations where the page is not tall enough to support a 1px scroll the script offers an automatic padding solution.
// Check that the current page can be scrolled first. Pad content if necessary.
if(document.documentElement.scrollHeight <= document.documentElement.clientHeight) {
// Extend body height to overflow and cause scrolling
bodyTag = document.getElementsByTagName('body')[0];
bodyTag.style.height = document.documentElement.clientWidth / screen.width * screen.height + 'px'; // Viewport height at fullscreen
}
The vertical page scroll is reset to zero after the hide. This means that single pixel highlights on elements that are at the top of the page are not lost.
If previously modified, the body height is also reset to exactly the window innerHeight.
Even if we don't go to all the above trouble it is much better to increment the scroll position instead of setting it to 1. This basic change would minimise the jump.
// Quick address bar hide on devices like the iPhone
//---------------------------------------------------
function quickHideAddressBar() {
setTimeout(function() {
if(window.pageYOffset !== 0) return;
window.scrollTo(0, window.pageYOffset + 1);
}, 1000);
}
You can reconstruct the idea from the given source or view the example source here.
Comments, suggestions or feedback via Optic Swerve on Twitter please.
Follow the author on Twitter.
‘Effortless responsive web design testing’.
Canvas Generated Icons. Read more.
Targeting Windows 8 Snap Mode. Read more.
CSS @viewport rule or viewport meta tag? Read more.
The Responsive Viewport. Missing piece of the responsive web design puzzle? Read more.
Getting the Viewport Scale.
Read more.
Hiding the iPhone Address Bar.
Read more.
Orientation Correct Screen Width.
Read more.
iPhone Title Modification.
Read more.
Optimising for High Pixel Density Displays.
Read more.
CSS3 Media Query Prototyping With ProtoFluid.
Read more.
AJAX Kill Switch. Version 2.
Read more.
URI Processing With JavaScript.
Read more.
All source code is provided for free.
A standard disclaimer of warranty and limitation of liability applies.