Bagaimana cara membuat IFrame responsif di iOS Safari?

134

Masalahnya adalah ketika Anda harus menggunakan IFrames untuk memasukkan konten ke situs web, maka di dunia web modern diharapkan bahwa IFrame juga akan responsif. Secara teori itu sederhana, hanya orang lain yang menggunakan <iframe width="100%"></iframe>atau mengatur lebar CSS untuk iframe { width: 100%; }namun dalam prakteknya tidak sesederhana itu, tetapi bisa jadi.

Jika iframekonten sepenuhnya responsif dan dapat mengubah ukurannya sendiri tanpa bilah gulir internal, maka iOS Safari akan mengubah ukurannya iframetanpa masalah nyata.

Jika Anda mempertimbangkan kode berikut:

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

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

Maka ini berfungsi tanpa masalah di iOS 7.1 Safari. Anda dapat mengubah antara lanskap dan potret tanpa masalah.

masukkan deskripsi gambar di sini masukkan deskripsi gambar di sini

Namun dengan hanya mengubah Content.html CSS dengan menambahkan ini:

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

Anda mendapatkan ini:

masukkan deskripsi gambar di sini masukkan deskripsi gambar di sini

Seperti yang Anda lihat, meskipun konten Content.html sepenuhnya responsif ( div # ScrolledArea telah overflow: scrollditetapkan) dan lebar iframe adalah 100% iframe masih mengambil lebar penuh dari div # ScrolledArea seolah-olah tidak ada luapan yang melimpah. Demo

Dalam kasus seperti ini, apakah iframekonten memiliki area gulir di atasnya, pertanyaannya menjadi, bagaimana mendapatkan iframeresponsif, ketika konten iframe memiliki area gulir secara horizontal? Masalahnya di sini bukan pada kenyataan bahwa Content.html tidak responsif, tetapi pada kenyataan bahwa Safari iOS hanya mengubah ukuran iframe sehingga div#ScrolledAreaakan sepenuhnya terlihat.

Idra
sumber
Bisakah Anda membagikan tautan dengan kami? Apakah Anda mengatakan bahwa iOS akan memperluas iFrame ke lebar penuh halaman dalam jika halaman di dalamnya memiliki konten dengan white-space: nowrapgaya?
DA.
@DA Saya menambahkan demo untuk masalah dan solusinya. Dan tidak, white-space: nowrapitu sendiri bukanlah masalahnya. Saya hanya menggunakannya untuk mendapatkan lebar ekstrim div#ScrolledArea. Masalahnya muncul ketika konten IFrame memiliki area yang dapat digulir secara horizontal di dalamnya. Jika itu yang terjadi, iOS Safari mengabaikan pengaturan lebar Anda dan menunjukkan konten lubang dan memecah respons situs.
Idra
Hmm ... Saya ingin tahu apakah itu 'fitur'. Akan aneh untuk memiliki area yang dapat digulir (iFrame) yang berisi konten yang dapat digulir. Ini akan menjadi hal yang sangat sulit untuk berinteraksi dengan di layar sentuh.
DA.
@DA Tentu saja ini adalah kasus keponakan, dan apa yang Anda katakan dapat benar (tergantung pada implementasinya, bekerja untuk kami) dan sebagian besar situs tidak memiliki area yang dapat digulir secara horizontal, tetapi ketika Anda melakukannya ... Anda bahkan tidak dapat membayangkan berapa banyak waktu yang saya habiskan untuk ini. Tapi ini bisa menjadi masalah bahkan jika Anda memiliki gambar yang disembunyikan dan digulir dengan tombol atau sesuatu seperti itu.
Idra
Sepertinya ada pertanyaan terkait tentang ini: stackoverflow.com/questions/5267996/... Tampaknya ini menjadi 'fitur' safari seluler ... ini berusaha memastikan bahwa konten sedang diukur dengan cara yang dapat dilakukan pengguna masih berinteraksi dengannya. Saya tidak yakin apa yang akan terjadi jika Anda memiliki konten gulir dalam iframe gulir ... bagaimana Safari menafsirkan gesekan dalam elemen gulir bersarang?
DA.

Jawaban:

289

Solusi untuk masalah ini sebenarnya cukup sederhana dan ada dua cara untuk mengatasinya. Jika Anda memiliki kendali atas Content.html maka cukup ubah div#ScrolledArealebar CSS menjadi:

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

Pada dasarnya ide di sini sederhana, Anda mengatur widthke sesuatu yang lebih kecil dari viewport (lebar iframe dalam kasus ini) dan kemudian menimpanya dengan min-width: 100%untuk memungkinkan width: 100%Safari iOS mana yang secara default ditimpa. Itu *width: 100%;ada sehingga kode akan tetap kompatibel IE6, tetapi jika Anda tidak peduli untuk IE6 Anda dapat menghilangkannya. Demo

masukkan deskripsi gambar di sini masukkan deskripsi gambar di sini

Seperti yang Anda lihat sekarang, div#ScrolledArealebarnya sebenarnya 100% dan overflow: scroll;bisa melakukan itu dan menyembunyikan konten yang meluap. Jika Anda memiliki akses ke konten iframe, maka ini lebih disukai.

Namun jika Anda tidak memiliki akses ke konten iframe (untuk alasan apa pun) maka Anda sebenarnya dapat menggunakan teknik yang sama pada iframe itu sendiri. Cukup gunakan CSS yang sama di iframe:

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

Namun, ada satu batasan dengan ini, Anda harus mematikan scrollbar dengan scrolling="no"iframe agar ini berfungsi:

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

Jika bilah gulir diizinkan, maka ini tidak akan berfungsi pada iframe lagi. Yang mengatakan, jika Anda mengubah Content.html, maka Anda dapat mempertahankan gulir di iframe. Demo

Idra
sumber
1
Seperti @NickGottlieb disebutkan, aku harus menambahkan !importantke widthatribut untuk mendapatkan iframe responsif-web-desain siap pada iPhone 4 dengan iOS 7
malisokan
@ ЮнгвиртТони Seharusnya tidak diperlukan untuk solusi untuk bekerja, ada kemungkinan bahwa widthtelah ditetapkan sebelumnya dengan !importantatau CSS prioritas tinggi menimpa itu. Dalam kasus terisolasi di iPhone 4 iOS7 itu tidak diperlukan.
Idra
Saya tidak perlu! Penting juga. Berfungsi bagus di iOS 8 juga. Cheers
Sam Potts
Saya perlu menggulir = tidak hanya bila perlu, jika tidak gulir = ya. Jadi apa yang harus saya deteksi? Apakah ini masalah iOS? atau masalah webkit? atau...?
gerbz
@ggwarpig ini adalah masalah iOS, di mana iOS Safari secara otomatis mengaktifkan atribut seamless dan Anda tidak dapat menimpanya. Jika Anda memiliki kontrol atas konten, maka Anda perlu mengubah konten agar memiliki scrolling="yes"sebaliknya, tidak ada cara untuk memperbaikinya, untuk memperbaiki untuk bekerja pada IFRAME saja Anda harus memiliki scrolling="no"pada IFRAME
Idra
24

Masalahnya, tampaknya, Mobile Safari akan menolak untuk mematuhi lebar iFrame Anda jika dokumen yang dikandungnya lebih luas dari yang Anda tentukan. Contoh:

http://jsbin.com/hapituto/1

Pada browser desktop, Anda akan melihat iFrame dan Div keduanya diatur ke 300px. Konten lebih luas sehingga Anda dapat menggulir iFrame.

Namun, pada safari seluler, Anda akan melihat bahwa iFrame diperluas secara otomatis ke lebar konten.

Dugaan saya adalah bahwa ini adalah solusi untuk masalah lama dengan menggulir konten di dalam halaman. Di masa lalu, jika Anda memiliki iframe gulir besar pada perangkat sentuh, Anda akan 'terjebak' di iframe karena itu akan menggulir bukannya halaman itu sendiri. Tampaknya Apple telah memutuskan bahwa perilaku default sebuah iFrame adalah 'no scroll' dan diperluas untuk mencegahnya.

Salah satu opsi mungkin adalah solusi ini. Alih-alih mengasumsikan iFrame akan menggulir, letakkan iframe dalam DIV yang Anda kendalikan dan biarkan gulir itu.

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

Markup contoh:

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

Di safari seluler, kini Anda dapat menggulir konten iFrame yang sekarang diperluas sepenuhnya melalui div yang berisi itu.

Tangkapan: Ini terlihat sangat jelek di browser desktop, karena sekarang Anda memiliki scrollbar ganda. Jadi, Anda mungkin harus melakukan beberapa deteksi browser dengan JS untuk menyiasatinya.

DA.
sumber
1
Saya akan tetap berpendapat bahwa ini tidak benar-benar dalam cakupan pertanyaan, karena solusi yang Anda tunjukkan di sini adalah cara standar cara memalsukan lubang iframe dengan bergulir di iOS Safari, tetapi dengan mempertimbangkan masalah iOS ini adalah masalah mengenai bergulir IFrame (konten atau sebaliknya) maka menyenangkan untuk memilikinya di sini.
Idra
1
Saya kira saya tidak sepenuhnya memahami pertanyaan Anda. Dari apa yang saya pahami, masalah yang Anda hadapi adalah di iOS, Mobile Safari mencoba mencegah iFrame untuk menggulir di tempat pertama dan memaksa lebar di atasnya. Apakah saya salah memahami masalah Anda?
DA.
Pada intinya itulah masalahnya, hanya saja solusi yang dibutuhkan berbeda. Dalam masalah awal, konten IFrame responsif, sementara memiliki konten gulir horizontal sehingga pertanyaannya bukan bagaimana meniru gulir iframe , tetapi bagaimana mendapatkan lebar iframe menjadi 100% yaitu responsif, sementara Anda memiliki konten gulir horizontal dengan di iframe itu. Itu sebabnya pendekatan di atas tidak berfungsi dalam kasus ini, karena responsif yang dirancang telah rusak dan Anda perlu menggulirkan sekitar untuk melihat konten lengkap, bahkan di tempat-tempat dengan desain yang biasanya Anda tidak perlu melakukannya.
Idra
1
Saya minta maaf, saya menyadari bahwa saya menyesatkan Anda pada salah satu komentar. Iframe tidak sedang bergulir. Itulah intinya, iframe tidak seharusnya hanya menggulung sebagian kontennya yaitu div#ScrolledArea(berwarna hijau) dalam contoh saya. Saya hanya salah baca sebelumnya. Tapi iframe tidak boleh bergulir hanya mengubah ukurannya sendiri berdasarkan elemen wadah yaituwidth: 100%;
Idra
18

Saya membutuhkan solusi lintas-browser. Persyaratan adalah:

  • diperlukan untuk bekerja di iOS dan di tempat lain
  • tidak memiliki akses ke konten di iFrame
  • membutuhkannya untuk menggulir!

Membangun apa yang saya pelajari dari @Idra tentang scrolling = "no" di iOS dan posting ini tentang pemasangan konten iFrame ke layar di iOS inilah yang akhirnya saya dapatkan. Semoga ini bisa membantu seseorang =)

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

}
gerbz
sumber
1
terbalik, tapi ... mengapa aturan IE6 di kelas "ios"? :-)
J. Bruni
12

Masalah dengan semua solusi ini adalah bahwa ketinggian yang iframetidak pernah benar-benar berubah.

Ini berarti Anda tidak akan dapat memusatkan elemen di dalam iframemenggunakan Javascript position:fixed;,, atau position:absolute;karenaiframe itu sendiri tidak pernah menggulir.

Solusi saya yang dirinci di sini adalah untuk membungkus semua konten iframe di dalam divmenggunakan CSS ini:

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

Dengan cara ini Safari meyakini konten tidak memiliki ketinggian dan memungkinkan Anda menetapkan ketinggian dengan iframebenar. Ini juga memungkinkan Anda untuk memposisikan elemen dengan cara apa pun yang Anda inginkan.

Anda dapat melihat demo cepat dan kotor di sini.

Dermaga
sumber
1
Ini adalah satu-satunya solusi yang berhasil untuk saya. Tentu saja, itu hanya dapat digunakan jika Anda mengontrol konten iframe, tetapi dalam kasus saya, saya lakukan. Bersulang!
Vince
Hmm. Contoh Anda sepertinya tidak responsif pada iOS?
BrandonReid
Itu 2 tahun yang lalu ketika saya menulis ini. Bisakah Anda mengajukan masalah dalam repo?
Dermaga
setelah menghabiskan berjam-jam pada masalah ini dengan Ionic / Cordova di iOS, ini adalah satu-satunya hal yang berhasil. Terima kasih!
Andrew
1
Ini luar biasa, satu-satunya yang berhasil, saya menghabiskan 1 hari mencari solusi seperti ini @Pier 100pts untuk Anda
Carlos E
5

Masalah ini juga ada di iOS Chrome.

Saya melihat-lihat semua solusi di atas, kebanyakan sangat hacky.

Jika Anda tidak memerlukan dukungan untuk browser lama, cukup atur lebar iframe ke 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 */
}

Catatan: Periksa dukungan untuk unit viewport https://caniuse.com/#feat=viewport-units

Prathamesh Gharat
sumber
1
Chrome untuk iOS hanya Safari di bawahnya. Ini menggunakan WKWebView. Tidak ada mesin rendering web lain yang diizinkan di iOS.
Dermaga
3

Saya bekerja dengan ionic2 dan konfigurasi sistem seperti di bawah ini-


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

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



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

Bagi saya masalah ini diselesaikan dengan kode ini -
untuk tag iframe html -

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

Lihat css dari


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

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

Posisi properti memainkan peran penting di sini dalam kasus saya.
posisi: relatif;

Ini dapat membantu Anda juga !!!

S.Yadav
sumber
0

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

Demo lain di sini dengan halaman HTML di iframe

4dgaurav
sumber
Mungkin saya salah mengimplementasikan solusi Anda, tetapi ketika saya mencobanya dengan test case terisolasi saya, maka tidak berhasil sama sekali di iOS Safari 7.1 iPhone 4. Bisakah Anda menguraikan bagaimana ini seharusnya bekerja?
Idra
OK itu sepertinya Anda salah paham masalah ini, periksa tautan ini bahwa itu adalah konten iframe demo baru Anda yang terintegrasi tanpa CSS tambahan yang diterapkan pada iframe. Dan jika Anda melihatnya di iOS Safari, maka itu masih responsif, ini karena halaman ini tidak memiliki scroll horizontal yang akan memaksa lebar iframe menjadi lebih lebar daripada viewport. Seperti dijelaskan dalam pertanyaan, di situs seperti ini Anda tidak perlu melakukan apa pun agar iframe responsif.
Idra
jadi apa sebenarnya yang Anda inginkan untuk berperilaku, berikan contoh untuk tautan yang Anda berikan?
4dgaurav
0

Saya memiliki masalah dengan lebar di panel konten yang membuat bilah gulir horizontal untuk iframe. Ternyata gambar memegang lebar lebih lebar dari yang diharapkan. Saya bisa menyelesaikannya dengan mengatur semua gambar css max-width menjadi persen.

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

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

sebenarnya bagi saya hanya bekerja di ios menonaktifkan scroll

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

dan memperlakukan OS melalui skrip.

Luiz Rossi
sumber
0

Bagi saya solusi CSS tidak berfungsi. Tetapi mengatur lebar secara pemrograman berfungsi. Pada beban iframe atur lebar secara terprogram:

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