How to get an IFrame to be responsive in iOS Safari?

Solution 1:

The solution for this problem is actually quite simple and there are two ways to go about it. If you have control over the Content.html then simply change the div#ScrolledArea width CSS to:

        width: 1px;
        min-width: 100%;
        *width: 100%;

Basically the idea here is simple, you set the width to something that is smaller than the viewport (iframe width in this case) and then overwrite it with min-width: 100% to allow for actual width: 100% which iOS Safari by default overwrites. The *width: 100%; is there so the code would remain IE6 compatible, but if you do not care for IE6 you can omit it. Demo

enter image description hereenter image description here

As you can see now, the div#ScrolledArea width is actually 100% and the overflow: scroll; can do it's thing and hide the overflowing content. If you have access to the iframe content, then this is preferable.

However if you do not have access to the iframe content (for what ever reason) then you can actually use the same technique on the iframe itself. Simply use the same CSS on the iframe:

    iframe {
        width: 1px;
        min-width: 100%;
        *width: 100%;
    }

However, there is one limitation with this, you need to turn off the scrollbars with scrolling="no" on the iframe for this to work:

<iframe height="950" width="100%" scrolling="no" src="Content.html"></iframe>

If the scrollbars are allowed, then this wont work on the iframe anymore. That said, if you modify the Content.html instead then you can retain the scrolling in the iframe. Demo

Solution 2:

The problem, it seems, is that Mobile Safari will refuse to obey the width of your iFrame if the document it contains is wider than what you have specified. Example:

http://jsbin.com/hapituto/1

On a desktop browser, you will see an iFrame and a Div both set to 300px. The contents is wider so you can scroll the iFrame.

On mobile safari, however, you will notice that the iFrame is auto-expanded to the width of the content.

My guess is that this is a workaround for long-standing issues with scrolling content within a page. In the past, if you had a large scrolling iframe on a touch device, you'd get 'stuck' in the iframe as that would be scrolling instead of the page itself. It appears Apple has decided that the default behavior of an iFrame is 'no scroll' and expands to prevent it.

One option may be this workaround. Instead of assuming the iFrame will scroll, place the iframe in a DIV that you do have control over and let that scroll.

example: http://jsbin.com/zakedaja/1

Example markup:

<div style="overflow: scroll; -webkit-overflow-scrolling: touch; width: 300px;">
   <iframe src="http://jsbin.com/roredora/1/" style="width: 600px;"></iframe>
</div>

On mobile safari, you can now scroll the contents of the now fully-expanded iFrame via the div that is containing it.

The catch: This looks really ugly on a desktop browser, as now you have double scrollbars. So you may have to do some browser detection with JS to get around this.