Scrolling iFrame on iOS

I just finished adding scrolling support to the RecordDialog class in Xataface for the iPad. The RecordDialog basically allows you to open an edit form or new record form in an iframe using a Javascript call. This is useful if you want to be able to pop up a form without the user having to navigate away from the page. It uses an iFrame for legacy reasons, until the forms API can be updated to work 100% through AJAX. This component has worked well for a long time on the desktop, and it works okay on the iPad and iPhone if the form fits inside the iframe without having to scroll. The trouble is that you can’t scroll an iframe on iOS, so if the form is too long, it just gets cut off and the user can’t see the bottom of the form.

After some Google searching I found a few strategies for overcoming this issue. The proposed solutions can be categorized into 3 groups, and all of the solutions have one common element: start by making the iframe unscrollable using the scrolling=”no” HTML attribute. From there, you can either:

  1. Set the iframe height to be as tall as the document body, and wrap the iframe in a scrollable div tag.
  2. Wrap the contents of the iframe in a scrollable div tag. (This requires sizing the DIV’s height to be the same as the iframe’s parent’s inner height).
  3. Use javascript touchStart and touchMove events to do scrolling with Javascript inside the iframe.

After experimenting with options #1 and #3, I settled on solution #2: wrapping the iframe’s contents because it seems to work best for all occasions. Of course this solution won’t work if you don’t own the contents of the iframe.

Option #1 (wrapping the iframe in a scrollable div) is problematic because, by changing the size of the iframe to be taller than the screen, potentially, it screws up calculations in the body of the iframe that rely on window height. I found that dialogs that are created to be displayed in the middle of the page end up displaying way down the page because the window is deemed to be effectively the size of the iframe, which has been artificially resized to be way too big.

Option #3 didn’t look as appealing because of the amount of custom javascript handling. I just have the feeling that I would have been starting down a long road of browser incompatibility glitches.

Resources

  • A good blog post on some of these strategies
  • A stack overflow conversation on the topic.
  • comments powered by Disqus