iOS 7 Safari: Breaking Changes for HTML5 Games

If you have any experience of making HTML5 games for mobile web browsers, you’ll recognise this bit of code:

// set height of the document to be greater than screen size
document.body.style.height = screen.height * 2 + 'px';

// scroll down the page a bit to hide url bar
window.scrollTo(0, 1);

// set the view frame to the height of window
if (window.innerWidth < window.innerHeight) {
    $frame.style.height = window.innerHeight + 'px';
}

This code is used to hide the URL bar in mobile browsers. The game view is fixed (using CSS) within the browser window – giving players the maximum space available to play your game.

iOS 6 on an iPhone 4S, window.scrollTo hack working

In iOS 7, Safari introduces ‘fullscreen browsing’ – as soon as a user scrolls down the page, both the url bar at the top and the navigation bar at the bottom are hidden from view. The bars are revealed again by browsing to the top of the page (or tapping the clock ‘scroll to the top’ shortcut).  This gives the user much more screen ‘real estate’ when browsing the web.

Unfortunately this feature, whilst being a step in the right direction for general purpose web consumption, is a real pain in the backside for HTML5 game developers. From my tests, it appears that any scroll behaviour must be user initiated. The window.scrollTo hack doesn’t work anymore. The page scrolls to whatever you set the Y value to, but then jumps back to Y = 0.

IMG_0075
iOS 7 on an iPhone 5, window.scrollTo hack no longer works 🙁

This change is going to (and has, because I’ve checked) cause problems for a lot of games. Luckily, the beta implementation of landscape mode never made it through to the final version.  That would have been a real nightmare for landscape-only games, because there was practically no viewport visible to play the game in.

IMG_0033-1
iOS 7 beta version of landscape mode
IMG_0077-1
iOS 7 final version of fullscreen landscape mode

This is bad news for HTML5 games and web apps alike.  I’d love to hear if you come up with a solution for this, because thus far, I’m stumped!