¿Cómo conseguir que un IFrame sea responsivo en iOS Safari?


El problema es que cuando tienes que usar IFrames para insertar contenido en un sitio web, entonces en el mundo web moderno se espera que el IFrame también sea responsivo. En teoría es simple, simplemente aider use <iframe width="100%"></iframe> o establezca el ancho CSS en iframe { width: 100%; } sin embargo, en la práctica no es tan simple, pero puede serlo.

Si el contenido iframe es totalmente responsivo y puede redimensionarse sin barras de desplazamiento internas, entonces iOS Safari redimensionará el iframe sin ningún valor real cuestión.

Si considera el siguiente código:

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

Con el Contenido .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>

Entonces esto funciona sin problemas en iOS 7.1 Safari. Puede cambiar entre horizontal y vertical sin ningún problema.

introduzca la descripción de la imagen aquíintroduzca la descripción de la imagen aquí

Sin embargo, simplemente cambiando el Contenido de .html CSS añadiendo esto:

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

Obtienes esto:

introduzca la descripción de la imagen aquíintroduzca la descripción de la imagen aquí

Como se puede ver, a pesar de que el Contenido .html el contenido es totalmente responsivo ( div#ScrolledArea tiene overflow: scrollestablecido) y el ancho del iframe es 100% el iframe todavía toma el ancho completo del div#ScrolledArea como si el desbordamiento ni siquiera existiera. Demo

En casos como este, si el contenido iframetiene áreas de desplazamiento en él, la pregunta es, ¿cómo obtener la respuesta iframe, cuando el contenido del iframe tiene áreas de desplazamiento horizontal? El problema aquí no está en el hecho de que el Contenido .html no responde, pero en el hecho de que el iOS Safari simplemente cambia el tamaño del iframe para que el div#ScrolledArea sería totalmente visible.

Author: Idra, 2014-04-15

9 answers

La solución para este problema es en realidad bastante simple y hay dos maneras de hacerlo. Si usted tiene control sobre el Contenido .html luego simplemente cambia el CSS div#ScrolledArea width a:

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

Básicamente la idea aquí es simple, se establece el width a algo que es más pequeño que el viewport (ancho iframe en este caso) y luego se sobrescribe con min-width: 100% para permitir real width: 100% que iOS Safari por defecto sobrescribe. El *width: 100%; está ahí para que el código permanezca IE6 compatible, pero si no te importa IE6 puedes omitirlo. Demo

introduzca la descripción de la imagen aquíintroduzca la descripción de la imagen aquí

Como puedes ver ahora, el ancho div#ScrolledArea es en realidad 100% y el overflow: scroll; puede hacerlo y ocultar el contenido desbordante. Si tiene acceso al contenido del iframe, entonces esto es preferible.

Sin embargo, si no tiene acceso al contenido del iframe (por cualquier razón), puede usar la misma técnica en el iframe. Simplemente use el mismo CSS en el iframe:

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

Sin embargo, hay una limitación con esto, necesita desactivar las barras de desplazamiento con scrolling="no" en el iframe para que esto funcione:

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

Si se permiten las barras de desplazamiento, esto ya no funcionará en el iframe. Dicho esto, si modifica el Contenido .html en su lugar, puede conservar el desplazamiento en el iframe. Demo

 241
Author: Idra,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-02-16 22:49:14

El problema, al parecer, es que Mobile Safari se negará a obedecer el ancho de su iFrame si el documento que contiene es más ancho de lo que ha especificado. Ejemplo:

Http://jsbin.com/hapituto/1

En un navegador de escritorio, verá un iFrame y un Div ambos configurados en 300px. El contenido es más ancho para que pueda desplazarse por el iFrame.

En mobile safari, sin embargo, notará que el iFrame se expande automáticamente al ancho del contenido.

Mi conjetura es que esta es una solución para problemas de larga data con el desplazamiento de contenido dentro de una página. En el pasado, si tenías un iframe de desplazamiento grande en un dispositivo táctil, te quedarías 'atascado' en el iframe, ya que se desplazaría en lugar de la página en sí. Parece que Apple ha decidido que el comportamiento predeterminado de un iFrame es 'no scroll' y se expande para evitarlo.

Una opción puede ser esta solución. En lugar de asumir que el iFrame se desplazará, coloque el iframe en un DIV que tenga control cambio y deja que se desplace.

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

Ejemplo de marcado:

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

En mobile safari, ahora puede desplazarse por el contenido del iFrame ahora completamente expandido a través del div que lo contiene.

La trampa: Esto se ve muy feo en un navegador de escritorio, ya que ahora tiene barras de desplazamiento dobles. Así que es posible que tenga que hacer algo de detección de navegador con JS para evitar esto.

 18
Author: DA.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-04-17 03:02:42

Necesitaba una solución cross-browser. Los requisitos eran:

  • necesario para trabajar tanto en iOS como en otros lugares
  • no tiene acceso al contenido del iFrame
  • necesito que se desplace!

Construyendo lo que aprendí de @Idracon respecto a scrolling="no" en iOS y este post sobre la adaptación de contenido iFrame a la pantalla en iOS esto es lo que terminé con. Espero que ayude a alguien =)

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

}
 10
Author: ggwarpig,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-04-19 19:29:10

El problema con todas estas soluciones es que la altura de la iframe nunca cambia realmente.

Esto significa que no podrá centrar elementos dentro de iframe usando Javascript, position:fixed;, o position:absolute; ya que el iframe nunca se desplaza.

Mi solución detallada aquí es envolver todo el contenido del iframe dentro de un div usando este CSS:

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

De esta manera Safari cree que el contenido no tiene altura y le permite asignar la altura de la iframe correctamente. Este también le permite colocar elementos de cualquier manera que desee.

Puedes ver una demostración rápida y sucia aquí.

 5
Author: Pier,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-07-22 19:27:28

Estoy trabajando con ionic2 y la configuración del sistema es la siguiente -


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

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



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

Para mí, este problema se resolvió con este código-
para 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>

Ver css de lo mismo que -


.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 propiedad Position juega un papel vital aquí en mi caso.
posición: relativa;

¡Puede ayudarte a ti también!!!

 1
Author: S.Yadav,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-11-16 12:25:15

Solución única de CSS

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

Otro demo aquí con página HTML en iframe

 0
Author: 4dgaurav,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-04-16 01:56:39

Tuve un problema con el ancho en el panel de contenido creando una barra de desplazamiento horizontal para el iframe. Resultó que una imagen sostenía el ancho más ancho de lo esperado. Pude resolverlo configurando el ancho máximo de css de todas las imágenes en un porcentaje.

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

img {
        max-width: 100%;
        height:auto;
    }
 0
Author: Dr. Aaron Dishno,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-08-18 21:13:27

De hecho para mí solo funcionó en ios desactivando el desplazamiento

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

Y tratando el sistema operativo a través de script.

 0
Author: Luiz Rossi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-05-17 20:48:50

Este problema también está presente en iOS Chrome.

En mi caso necesitaba un Eché un vistazo a todas las soluciones anteriores, la mayoría son muy hacky.

Si no necesita soporte para navegadores más antiguos, simplemente establezca el ancho del iframe en 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 */ }

Nota: Compruebe el soporte para unidades viewport https://caniuse.com/#feat=viewport-units

 0
Author: Prathamesh Gharat,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-09-13 08:33:49