web-dev-qa-db-fra.com

Comment faire en sorte qu'un IFrame soit réactif dans iOS Safari?

Le problème est que, lorsque vous devez utiliser IFrames pour insérer du contenu dans un site Web, dans le monde Web moderne, on s'attend à ce que l'IFrame soit également réactif. En théorie, rien de plus simple, il vous suffit simplement d’utiliser <iframe width="100%"></iframe> ou de définir la largeur CSS sur iframe { width: 100%; }. Toutefois, dans la pratique, ce n’est pas aussi simple, mais cela peut être.

Si le contenu iframe est entièrement réactif et peut se redimensionner lui-même sans barres de défilement internes, iOS Safari redimensionnera la iframe sans problème réel.

Si vous considérez le code suivant:

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

Avec le 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>

Ensuite, cela fonctionne sans problèmes dans iOS 7.1 Safari. Vous pouvez basculer entre paysage et portrait sans aucun problème.

enter image description hereenter image description here

Cependant, en changeant simplement le Content.html CSS en ajoutant ceci:

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

Vous obtenez ceci:

enter image description hereenter image description here

Comme vous pouvez le constater, même si le contenu de Content.html est entièrement réactif (div # ScrolledArea a overflow: scroll défini) et que sa largeur est de 100%, l'iframe prend toujours toute sa largeur. le div # ScrolledArea comme si le débordement n'existait même pas. Démo

Dans de tels cas, si le contenu iframe comporte des zones de défilement, la question est de savoir comment obtenir la réponse iframe lorsque le contenu de l’iframe comporte des zones de défilement horizontal. Le problème ici n'est pas dans le fait que le Content.html n'est pas réactif, mais dans le fait qu'iOS Safari redimensionne simplement l'iframe afin que le div#ScrolledArea soit entièrement visible.

111
Idra

La solution à ce problème est en fait assez simple et il y a deux façons de s'y prendre. Si vous avez le contrôle sur Content.html, remplacez simplement le CSS div#ScrolledArea width par:

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

En gros, l’idée est simple: vous définissez la variable width sur une valeur plus petite que la fenêtre de visualisation (iframe width dans ce cas), puis vous la remplacez par min-width: 100% afin de permettre à width: 100% réel d’écraser par défaut iOS Safari. Le *width: 100%; est là pour que le code reste compatible avec IE6, mais si vous ne vous souciez pas de IE6, vous pouvez l'omettre. Démo

enter image description hereenter image description here

Comme vous pouvez le constater maintenant, la largeur de div#ScrolledArea est en fait de 100% et le overflow: scroll; peut tout faire et cacher le contenu débordant. Si vous avez accès au contenu d'iframe, cela est préférable. 

Toutefois, si vous n'avez pas accès au contenu de l'iframe (pour quelque raison que ce soit), vous pouvez utiliser la même technique sur l'iframe lui-même. Utilisez simplement le même CSS sur l'iframe:

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

Cependant, il y a une limite à cela, vous devez désactiver les barres de défilement avec scrolling="no" sur l'iframe pour que cela fonctionne:

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

Si les barres de défilement sont autorisées, cela ne fonctionnera plus sur l'iframe. Cela dit, si vous modifiez plutôt Content.html, vous pouvez conserver le défilement dans l'iframe. Démo

258
Idra

Le problème, semble-t-il, est que Mobile Safari refusera d'obéir à la largeur de votre iFrame si le document qu'il contient est plus large que ce que vous avez spécifié. Exemple:

http://jsbin.com/hapituto/1

Sur un navigateur de bureau, vous verrez un iFrame et un Div tous deux réglés sur 300px. Le contenu est plus large afin que vous puissiez faire défiler l'iFrame.

Sur safari mobile, toutefois, vous remarquerez que l'iFrame est automatiquement étendu à la largeur du contenu. 

Mon hypothèse est qu'il s'agit d'une solution de contournement pour les problèmes de longue date liés au défilement de contenu dans une page. Dans le passé, si vous aviez un grand iframe à défilement sur un périphérique tactile, vous seriez "coincé" dans le iframe car ce serait le défilement au lieu de la page elle-même. Il semble qu'Apple ait décidé que le comportement par défaut d'un iFrame soit «pas de défilement» et se développe pour l'empêcher. 

Une solution peut être cette solution de contournement. Au lieu de supposer que l'iFrame défilera, placez l'iframe dans une DIV sur laquelle vous avez le contrôle et laissez-le défiler. 

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

Exemple de balisage:

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

Sur safari mobile, vous pouvez maintenant faire défiler le contenu de l'iFrame, désormais entièrement développé, via le div qui le contient.

Le piège: Cela semble vraiment moche sur un navigateur de bureau, car maintenant vous avez double barres de défilement. Vous devrez donc peut-être effectuer une détection de navigateur avec JS pour résoudre ce problème. 

19
DA.

J'avais besoin d'une solution multi-navigateur. Les exigences étaient:

  • devait fonctionner sur iOS et ailleurs
  • ne pas avoir accès au contenu de l'iFrame
  • besoin de faire défiler!

Construire ce que j’ai appris de @Idra concernant le défilement = "non" sur iOS et ce message sur l’ajustement du contenu iFrame à l’écran dans iOS, voici ce que j’ai trouvé. J'espère que ça aide quelqu'un =)

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

}
13
ggwarpig

Le problème avec toutes ces solutions est que la hauteur de iframe ne change jamais vraiment.

Cela signifie que vous ne pourrez pas centrer les éléments de la iframe à l'aide de Javascript, position:fixed; ou position:absolute; car la iframe ne défile jamais.

Ma solution détaillée ici consiste à envelopper tout le contenu de l'iframe dans une div à l'aide de ce CSS:

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

Ainsi, Safari estime que le contenu n'a pas de hauteur et vous permet d'affecter correctement la hauteur de la variable iframe. Cela vous permet également de positionner les éléments comme vous le souhaitez.

Vous pouvez voir une démo rapide et sale ici.

7
Pier

Je travaille avec ionic2 et la configuration du système est la suivante: 


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

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



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

Pour moi, ce problème a été résolu avec ce code-
pour 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>

Voir css de la même 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%;
}

La propriété de position joue un rôle essentiel ici dans mon cas.
position: relative;

Cela peut vous aider aussi !!!

3
S.Yadav

en fait pour moi vient de travailler dans iOS en désactivant le défilement

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

et traiter le système d'exploitation via un script.

0
Luiz Rossi

Pour moi, les solutions CSS ne fonctionnaient pas. Mais définir la largeur par programme fait le travail. Iframe load définit la largeur par programmation:

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

Ce problème est également présent sur iOS Chrome.

Dans mon cas, j'avais besoin d'un J'ai parcouru toutes les solutions ci-dessus, la plupart sont très bidon.

Si vous n'avez pas besoin de la prise en charge des navigateurs plus anciens, définissez simplement la largeur de l'iframe sur 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 */ }

Remarque: vérifiez la prise en charge des unités de viewport https://caniuse.com/#feat=viewport-units

0
Prathamesh Gharat

Solution CSS uniquement

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

Une autre démo ici avec une page HTML dans iframe

0
4dgaurav

J'ai eu un problème avec la largeur dans le volet contenu en créant une barre de défilement horizontale pour l'iframe. Il s'est avéré qu'une image maintenait la largeur plus large que prévu. J'ai pu résoudre le problème en réglant la largeur maximale de toutes les images css sur un pourcentage. 

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

img {
        max-width: 100%;
        height:auto;
    }
0
Dr. Aaron Dishno