iOS WebKit iframe错误说明
iOS WebKit将iframe调整为其内容的完整大小(参见下图)。这是一个自2016年以来已知的错误,但仍未在iOS 11中解决:https://bugs.webkit.org/show_bug.cgi?id=155198
我目前的调查结果
1。对于固定的iframe内容(例如视频)
下面应用CSS就足够了,但它可以防止iframe内容滚动。
.fixed iframe {
width: 0;
height: 0;
min-width: 100%;
min-height: 100%;
}
2。对于可滚动的iframe内容(例如页面)
有些RWD页面(假设“不完整的RWD”)正在遇到iframe溢出(iframe不适合iframe容器)。 不幸的是,我们无法从iframe中解决这个问题并解决此问题,iframe中的文档至少需要:
body {
max-width: 100vw !important;
}
我们可以选择扩展iframe内容作为最后的手段。
由于2,为了保持容器比例,我们至少需要使用CSS媒体查询或JS来调整其高度。
一些不完整的解决方案:
我的解决方法已发布在答案中。
答案 0 :(得分:10)
这就是我到目前为止所做的。任何贡献都非常赞赏。 Github Gist上的最新版本。
/* 1. Beautifiers (optional) */
iframe {
border: none;
width: 100%;
height: 100%;
}
.simple-container {
width: 50vw;
height: 50vh;
padding: 1em;
}
/* 2. Resolving iOS iframe rendering issue */
/* 2.1. Sizing reorganization (obligatory) */
.popover {
/* To control popover size by .popover-body instead of .popover */
max-width: 100% !important;
}
.popover-body {
box-sizing: border-box;
max-width: 100%;
max-height: 100%;
}
.iframe-container,
.iframe-container iframe {
width: 100%;
height: 100%;
margin: 0 !important;
padding: 0 !important;
box-sizing: border-box;
}
.fixed iframe {
/* This only fits iframe inside iframe-container but prevents scrolling */
width: 0;
height: 0;
min-width: 100%;
min-height: 100%;
}
.popover-body {
width: 640px; height: 360px;
}
/* 2.2. RWD Resizings (optional) */
@media only screen and (max-width: 568px)
{
.rwd .popover-body {
width: 320px; height: 180px;
}
}
@media only screen and (min-width: 569px) and (max-width: 965px)
{
.rwd .popover-body {
width: 480px; height: 270px;
}
}
@media only screen and (min-width: 968px) and (max-width: 1023px)
{
.rwd .popover-body {
width: 640px; height: 360px;
}
}
/* 2.3. Resolving iOS iframe scrolling issue (obligatory) */
/*
Due to iOS WebKit bug an iframe content cannot be scrolled, because WebKit renders entire iframe content:
https://bugs.webkit.org/show_bug.cgi?id=155198
(still not resolved on iOS11)
The workaround is to scroll an div container content with full iframe rendered inside.
*/
.scroll {
overflow: scroll !important;
-webkit-overflow-scrolling: touch !important;
}
/* 2.4. Resolving iframe and container double scrollbars on desktop browsers (rather obligatory) */
.no-scrollbar {
position: relative;
}
.no-scrollbar iframe {
position: absolute;
top: 0;
left: 0;
}
.no-scrollbar {
/* Hide scrollbars in IE Edge */
/* Autohiding is needed inside iframe document */
/*-ms-overflow-style: -ms-autohiding-scrollbar;*/
/* In the parent iframe container we don't want any scrollbars */
-ms-overflow-style: none;
}
/* 3. Scale non-RWD iframe content (optional) */
/* Warning! iOS 11 Safari crashes on two-fingers zoom of a page with scaled iframe */
.scale {
-ms-transform-origin: 0 0;
-moz-transform-origin: 0 0;
-o-transform-origin: 0 0;
-webkit-transform-origin: 0 0;
transform-origin: 0 0;
}
.scale.x2 {
width: 200% !important;
height: 200% !important;
-ms-transform: scale(0.5);
-moz-transform: scale(0.5);
-o-transform: scale(0.5);
-webkit-transform: scale(0.5);
transform: scale(0.5);
}
.scale.x4 {
width: 400% !important;
height: 400% !important;
-ms-transform: scale(0.25);
-moz-transform: scale(0.25);
-o-transform: scale(0.25);
-webkit-transform: scale(0.25);
transform: scale(0.25);
}
/* DEBUG */
/* To receive click events on iOS */
/*
* {
cursor: pointer;
}
*/
.popover-body {
border: 1px green dotted;
}
.simple-container,
.iframe-container {
border: 1px blue dotted;
}
iframe {
border: 1px red dotted;
}
<!DOCTYPE html>
<html lang="en">
<head>
<title>iOS iframes</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta http-equiv="cache-control" content="no-cache" />
<!-- Solution -->
<link rel="stylesheet" href="iframe.css" />
<!-- Bootstrap with Popover -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" />
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.bundle.min.js"></script>
<script>
jQuery(function ($) {
$('a.popover-me').on('click', function(e) {
e.preventDefault();
if (!$(this).data('bs.popover')) $(this).popover({
container: 'body',
boundary: 'window',
placement: 'auto',
trigger: 'manual',
html: true,
title: $(this).text(),
content: '<div class="iframe-container scroll no-scrollbar"><iframe src="' + this.href + '"></iframe></div>'
});
$(this).popover('toggle');
});
});
</script>
</head>
<body class="rwd" style="padding: 2em;">
<h2>Embracing iOS WebKit weirdness with iframes</h2>
<div class="alert alert-primary" role="alert">
Ready for Bootstrap v4.0.0 <a class="popover-me" href="https://en.wikipedia.org/wiki/WebKit">Popover</a>.
</div>
<div class="alert alert-danger" role="alert">
Display this page on iOS device.
</div>
<h3>1. Workaround for scrollable iframe</h3>
<p>
<div class="popover-body">
<div class="iframe-container scroll no-scrollbar">
<iframe src="https://en.wikipedia.org/wiki/WebKit"></iframe>
</div>
</div>
</p>
<div class="alert alert-warning" role="alert">
<strong>Hint: </strong>
<em>
Some RWD pages (let's say with "incomplete RWD") are experiencing iframe overflow (iframe does not fit into the iframe-container).
Unfortunately, we can't fix that from the iframe outside and to solve this issue, document inside iframe requires at least:
</em>
<br /><br />
<pre>
body {
/* Resolves iOS overflow rendering bug */
max-width: 100vw !important;
}
</pre>
<em>
Optionally, you can scale iframe document as below.
</em>
</div>
<h3>2. Workaround for non-RWD scrollable iframe</h3>
<em>
Page inside iframe is zoomed out to 50%.
</em>
<p>
<div class="popover-body">
<div class="iframe-container scroll no-scrollbar scale x2">
<iframe src="https://en.wikipedia.org/wiki/WebKit"></iframe>
</div>
</div>
</p>
<h3>3. Workaround for fixed iframe</h3>
<em>
iframe fits in iframe-container.
</em>
<p>
<div class="popover-body">
<div class="iframe-container fixed scroll no-scrollbar">
<iframe src="https://en.wikipedia.org/wiki/WebKit"></iframe>
</div>
</div>
</p>
<h3>4. [BUG] Plain iframe inside simple container</h3>
<em>
iframe should fit into simple container.
</em>
<p>
<div class="simple-container">
<iframe src="https://en.wikipedia.org/wiki/WebKit"></iframe>
</div>
</p>
</body>
</html>