[html] How to get an IFrame to be responsive in iOS Safari?

The problem is that when you have to use IFrames to insert content into a website, then in the modern web-world it is expected that the IFrame would be responsive as well. In theory it's simple, simply aider use <iframe width="100%"></iframe> or set the CSS width to iframe { width: 100%; } however in practice it's not quite that simple, but it can be.

If the iframe content is fully responsive and can resize itself without internal scroll bars, then iOS Safari will resize the iframe without any real issues.

If you consider the following code:

<html>
<head>
    <meta http-equiv="X-UA-Compatible" content="IE=9,10,11" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>Iframe Isolation Test</title>

    <style type="text/css" rel="stylesheet">

        #Main {
            padding: 10px;
        }
    </style>
</head>
<body>
    <h1>Iframe Isolation Test 13.17</h1>
    <div id="Main">
        <iframe height="950" width="100%" src="Content.html"></iframe>
    </div>
</body>
</html>

With the Content.html:

<html>
<head>
    <meta http-equiv="X-UA-Compatible" content="IE=9,10,11" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>Iframe Isolation Test - Content</title>

    <style type="text/css" rel="stylesheet">

        #Main {
            width: 100%;
            background: #ccc;
        }

    </style>
</head>
<body>
    <div id="Main">
        <div id="ScrolledArea">
            Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc malesuada purus quis commodo convallis. Fusce consectetur mauris eget purus tristique blandit. Nam nec volutpat augue. Aliquam sit amet augue vitae orci fermentum tempor sit amet gravida augue. Pellentesque convallis velit eu malesuada malesuada. Aliquam erat volutpat. Nam sollicitudin nulla nec neque viverra, non suscipit purus tincidunt. Aenean blandit nisi felis, sit amet ornare mi vestibulum ac. Praesent ultrices varius arcu quis fringilla. In vitae dui consequat, rutrum sapien ut, aliquam metus. Proin sit amet porta velit, suscipit dignissim arcu. Cras bibendum tellus eu facilisis sodales. Vestibulum posuere, magna ut iaculis consequat, tortor erat vulputate diam, ut pharetra sapien massa ut magna. Donec massa purus, pharetra sed pellentesque nec, posuere ut velit. Nam venenatis feugiat odio quis tristique. 
        </div>      
    </div>
</body>
</html>

Then this works without issues in iOS 7.1 Safari. You can change between landscape and portrait without any issues.

enter image description here enter image description here

However by simply changing the Content.html CSS by adding this:

    #ScrolledArea {
        width: 100%;
        overflow: scroll;
        white-space: nowrap;
        background: #ff0000;
    }

You get this:

enter image description here enter image description here

As you can see, even though the Content.html content is fully responsive (div#ScrolledArea has overflow: scroll set) and the iframe width is 100% the iframe still takes the full width of the div#ScrolledArea as if the overflow does not even exist. Demo

In cases like this, were the iframecontent has scrolling areas on it, the question becomes, how to get the iframe responsive, when the iframe content has horizontally scrolling areas? The problem here is not in the fact that the Content.html is not responsive, but in the fact that the iOS Safari simply resizes the iframe so that the div#ScrolledArea would be fully visible.

This question is related to html css iframe

The answer is


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!!!


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.


CSS only solution

HTML

<div class="container">
    <div class="h_iframe">
        <iframe  src="//www.youtube.com/embed/9KunP3sZyI0" frameborder="0" allowfullscreen></iframe>
    </div>
</div>

CSS

html,body {
    height:100%;
}
.h_iframe iframe {
    position:absolute;
    top:0;
    left:0;
    width:100%;
    height:100%;
}

DEMO

Another demo here with HTML page in iframe


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);

}

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;
    }

in fact for me just worked in ios disabling the scroll

<iframe src="//www.youraddress.com/" scrolling="no"></iframe>

and treating the OS via script.


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


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.


For me CSS solutions didn't work. But setting the width programmatically does the job. On iframe load set the width programmatically:

 $('iframe').width('100%');

Examples related to html

Embed ruby within URL : Middleman Blog Please help me convert this script to a simple image slider Generating a list of pages (not posts) without the index file Why there is this "clear" class before footer? Is it possible to change the content HTML5 alert messages? Getting all files in directory with ajax DevTools failed to load SourceMap: Could not load content for chrome-extension How to set width of mat-table column in angular? How to open a link in new tab using angular? ERROR Error: Uncaught (in promise), Cannot match any routes. URL Segment

Examples related to css

need to add a class to an element Using Lato fonts in my css (@font-face) Please help me convert this script to a simple image slider Why there is this "clear" class before footer? How to set width of mat-table column in angular? Center content vertically on Vuetify bootstrap 4 file input doesn't show the file name Bootstrap 4: responsive sidebar menu to top navbar Stylesheet not loaded because of MIME-type Force flex item to span full row width

Examples related to iframe

Getting all files in directory with ajax YouTube Autoplay not working Inserting the iframe into react component How to disable auto-play for local video in iframe iframe refuses to display iFrame onload JavaScript event YouTube iframe embed - full screen Change New Google Recaptcha (v2) Width load iframe in bootstrap modal Responsive iframe using Bootstrap