Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

html

css

iframe

People also ask

Does Safari support iframes?

See full reference on MDN Web Docs. 1 Safari has a bug that prevents iframes from loading if the iframe element was hidden when added to the page.

Can I make an iframe responsive?

iframes cannot be responsive. You can make the iframe container responsive but not the content it is displaying since it is a webpage that has its own set height and width. The example fiddle link works because it's displaying an embedded youtube video link that does not have a size declared.


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


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.


I needed a cross-browser solution. Requirements were:

  • needed to work on both iOS and elsewhere
  • don't have access to the content in the iFrame
  • need it to scroll!

Building off what I learned from @Idra regarding scrolling="no" on iOS and this post about fitting iFrame content to the screen in iOS here's what I ended up with. Hope it helps someone =)

HTML

<div id="url-wrapper"></div>

CSS

html, body{
    height: 100%;
}

#url-wrapper{
    margin-top: 51px;
    height: 100%;
}

#url-wrapper iframe{
    height: 100%;
    width: 100%;
}

#url-wrapper.ios{
    overflow-y: auto;
    -webkit-overflow-scrolling:touch !important;
    height: 100%;
}

#url-wrapper.ios iframe{
    height: 100%;
    min-width: 100%;
    width: 100px;
    *width: 100%;
}

JS

function create_iframe(url){

    var wrapper = jQuery('#url-wrapper');

    if(navigator.userAgent.match(/(iPod|iPhone|iPad)/)){
        wrapper.addClass('ios');
        var scrolling = 'no';
    }else{
        var scrolling = 'yes';
    }

    jQuery('<iframe>', {
        src: url,
        id:  'url',
        frameborder: 0,
        scrolling: scrolling
    }).appendTo(wrapper);

}

The problem with all these solutions is that the height of the iframe never really changes.

This means you won't be able to center elements inside the iframe using Javascript, position:fixed;, or position:absolute; since the iframe itself never scrolls.

My solution detailed here is to wrap all the content of the iframe inside a div using this CSS:

#wrap {
    position: fixed;
    top: 0;
    right:0;
    bottom:0;
    left: 0;
    overflow-y: scroll;
    -webkit-overflow-scrolling: touch;
}

This way Safari believes the content has no height and lets you assign the height of the iframe properly. This also allows you to position elements in any way you wish.

You can see a quick and dirty demo here.


This issue is also present on iOS Chrome.

I glanced through all the solutions above, most are very hacky.

If you don't need support for older browsers, just set the iframe width to 100vw;

iframe {
  max-width: 100%; /* Limits width to 100% of container */
  width: 100vw; /* Sets width to 100% of the viewport width while respecting the max-width above */
}

Note : Check support for viewport units https://caniuse.com/#feat=viewport-units


I am working with ionic2 and system config is as below-


******************************************************

Your system information:

Cordova CLI: 6.4.0 
Ionic Framework Version: 2.0.0-beta.10
Ionic CLI Version: 2.1.8
Ionic App Lib Version: 2.1.4
ios-deploy version: Not installed
ios-sim version: 5.0.8 
OS: OS X Yosemite
Node Version: v6.2.2
Xcode version: Xcode 7.2 Build version 7C68



******************************************************

For me this issue got resolved with this code-
for html iframe tag-

<div class="iframe_container">
      <iframe class= "animated fadeInUp" id="iframe1" [src]='page' frameborder="0" >
        <!--  <img src="img/video-icon.png"> -->
      </iframe><br>
   </div>

See css of the same as-


.iframe_container {
  overflow: auto; 
  position: relative; 
  -webkit-overflow-scrolling: touch;
  height: 75%;
}

iframe {
  position:relative;
  top: 2%;
  left: 5%;
  border: 0 !important;
  width: 90%;
}

Position property play a vital role here in my case.
position:relative;

It may help you too!!!


I had an issue with width on the content pane creating a horizontal scroll bar for the iframe. It turned out that an image was holding the width wider than expected. I was able to solve it by setting the all of the images css max-width to a percent.

<meta name="viewport" content="width=device-width, initial-scale=1" />

img {
        max-width: 100%;
        height:auto;
    }