【问题标题】:Workaround to iOS 11 WebKit iframe bugsiOS 11 WebKit iframe 错误的解决方法
【发布时间】:2018-09-19 19:49:22
【问题描述】:

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 内容(例如页面)

  1. 我们需要两个 iframe 容器:一个作为边界(固定大小),另一个作为滚动区域。
  2. 为了适应 iframe 内容,它的 div 容器必须以像素为单位定义 w/h。任何相对度量(如 %、vw/vh)都不起作用。
  3. 一些 RWD 页面(比如“不完整的 RWD”)遇到 iframe 溢出(iframe 不适合 iframe 容器)。 不幸的是,我们无法从外部 iframe 解决这个问题,为了解决这个问题,iframe 内的文档至少需要:

    body {
        max-width: 100vw !important;
    }
    

    我们可以选择缩放 iframe 内容作为最后的手段。

  4. 因为2,为了保持容器的比例,我们至少需要使用CSS媒体查询或者JS来调整它的高度。

一些不完整的解决方案

我的解决方法已发布在答案中。

【问题讨论】:

    标签: iframe mobile-webkit


    【解决方案1】:

    这就是我到目前为止所做的。任何贡献都非常感谢。 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>

    【讨论】:

      猜你喜欢
      • 2019-03-20
      • 1970-01-01
      • 1970-01-01
      • 2020-01-15
      • 1970-01-01
      • 2011-12-07
      • 2012-06-15
      • 2018-01-02
      • 1970-01-01
      相关资源
      最近更新 更多