This is something I never really noticed until it bit me. When Apple released IOS7 they made some rather interesting changes to Safari, in my case the main issue was how the address and bookmark bars are now toggled and a position fixed bug that seems related to it.
The summary of the Safari bars issues are when these bars are now toggled they no longer trigger the resize event like they did pre IOS7 and there is a 40px or so hit box running along the bottom of every viewport to show the bars which cannot be overridden and completely eats tap and click events. For more info please read this very useful post over at mobilexweb.com that lists the issues under the headings:
- FULL SCREEN AND BIG PROBLEMS FOR HTML5 APPS AND GAMES
- BOTTOM TOOLBARS AND INTERACTIVE ELEMENTS
While this may not sound like much it’s a huge problem if you have a website or plugin that uses the entire screen or has a footer bar with buttons or menus, when you try to use that bottom area of the screen any user touch will trigger the address and bookmark bars to appear forcing them to scroll down to make them hide again.
The second part of my problem is a fixed position bug that seems to occur along with the address and bookmark bars being toggled. The images below show the issue. Note how the red and blue bars are positioned in the second image compared to the third one. I created a small demo project with two pages in it over on GitHub that you can grab here to test the issue yourself, the images below are created from it.
The first image shows what the test pages look like with the address and bookmarks bar hidden. If you then attempt to tap on the blue bar on the issue.html page you will see what is shown in the second image. Instead of being positioned on the bottom of the viewport as seen in the third image and the fix.html page, the blue bar is pushed down by the amount the address bar height has grown and is overlapped by the bookmarks bar.
This behavior seems to only occur with fixed or absolutely positioned elements contained within another fixed position element, in this case a div used for a modal. You can see the HTML and CSS for this by looking at either of the HTML pages in the demo project.
Once I could detect the bar state I needed a way to force Safari to redraw the page. While I found many ways said to accomplish this, the only way that actually got results for me was to simply tell the browser to scroll to it’s current scroll position.
The code above for detecting the bar state then needed to be updated a little so as to only redraw the page once per state change for obvious performance reasons. For this I added a variable to hold the bar state and check it in the if statements. I also wanted to trigger the resize event like it used to pre IOS7 so the final code I arrived at is the below.
Now while I am not to thrilled about having to use code like this in my plugins, in this case it was necessary to get core functionality working again. Hopefully this can help any other developers that have encountered this issue and are looking for a temporary fix until this is patched and we can remove the code.