【问题标题】:Set width/height of image to avoid reflow on image load设置图像的宽度/高度以避免图像加载时重排
【发布时间】:2013-05-26 21:40:47
【问题描述】:

当我在html中使用图片标签时,我会尝试在img标签中指定它的宽度和高度,这样浏览器就会在图片加载之前为它们保留空间,所以当它们完成加载时,页面不重排(元素不移动)。例如:

<img width="600" height="400" src="..."/>

现在的问题是我想创建一个更“响应”的版本,对于“单列案例”,我想这样做:

<img style="max-width: 100%" src="..."/>

但是,如果我将它与明确指定的宽度和高度混合,例如:

<img style="max-width: 100%" width="600" height="400" src="..."/>

并且图像比可用空间宽,然后忽略纵横比调整图像大小。我明白为什么会发生这种情况(因为我“固定”了图像的高度),我想解决这个问题,但我不知道如何解决。

总结一下:我希望能够指定max-width: 100%,并以某种方式确保在加载图像时内容不会重排。

【问题讨论】:

  • 试试this solution!
  • 或许这篇文章能帮你解决问题:voorhoede.nl/en/blog/say-no-to-image-reflow
  • @Dennis:链接的帖子描述了与此问题的最佳答案相同的解决方案。
  • @Ry- 好吧,但也许这篇文章会解释更多,只是针对有同样问题但不明白到底发生了什么的人。但感谢您的信息!

标签: html image css responsive-design


【解决方案1】:

我也在寻找这个问题的答案。使用max-widthwidth=height=,浏览器有足够的数据应该能够为图像留出适量的空间,但它似乎不起作用方式。

我现在使用 jQuery 解决方案来解决这个问题。它要求您为&lt;img&gt; 标签提供width=height=

CSS:

img { max-width: 100%; height: auto; }

HTML:

<img src="image.png" width="400" height="300" />

jQuery:

$('img').each(function() { 
    var aspect_ratio = $(this).attr('height') / $(this).attr('width') * 100;
    $(this).wrap('<div style="padding-bottom: ' + aspect_ratio + '%">');
});

这会自动应用在以下位置看到的技术:http://andmag.se/2012/10/responsive-images-how-to-prevent-reflow/

【讨论】:

    【解决方案2】:

    对于纯 CSS 解决方案,您可以将 img 包装在一个容器中,其中 padding-bottom 百分比在页面上保留空间,直到图像加载,防止回流。

    不幸的是,这种方法确实需要您通过计算(或让 css 为您计算)基于图像高度和宽度的 padding-bottom 百分比,在您的 css 中包含图像纵横比(但不需要内联样式)。

    如果可以将您的许多图像分组为几个标准纵横比,那么您可以为每个纵横比创建一个类,以将适当的padding-bottom 百分比应用于具有该纵横比的所有图像。如果您不处理各种图像纵横比,这可能会为您节省一点时间和精力。

    以下是 2:1 纵横比图像的一些示例 html 和 css:

    HTML

    <div class="container">
      <img id="image" src="https://via.placeholder.com/300x150" />
    </div>
    

    CSS

    .container {
      display: block;
      position: relative;
      padding-bottom: 50%; /* calc(100%/(300/150)); */
      height: 0;
    }
    
    .container img {
      position: absolute;
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;
    }
    

    下面的 sn-p 添加了一些额外的 html、css 和 javascript 来创建一些可视的顶部和底部参考点并模拟一个非常缓慢的加载图像,因此您可以直观地看到这种方法是如何防止回流的。

    const image = document.getElementById('image');
    const source = 'https://via.placeholder.com/300x150';
    const changeSource = () => image.src = source;
    
    setTimeout(changeSource, 3000);
    .container {
      display: block;
      position: relative;
      padding-bottom: 50%; /* calc(100%/(300/150)); */
      height: 0;
    }
    
    .container img {
      position: absolute;
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;
    }
    
    .top, .bottom {
      background-color: green;
      width: 100%;
      height: 20px;
    }
    <div class="top"></div>
    <div class="container">
      <img id="image" src="" />
    </div>
    <div class="bottom"></div>

    【讨论】:

    • @Ry- 我认为你是对的,真的没有简单的 CSS 方法来防止来自不同纵横比的图像回流。更新了这个答案以供我自己参考,以便我可以在将来以及是否将更多预处理器功能添加到本机 css 时回到这个测试目的。如果您偶然发现了一些很棒的东西(不幸的是,迄今为止没有一个答案 - 包括我的 - 与该描述相符),请发布它。
    【解决方案3】:

    更新 2:(2019 年 12 月)

    Firefox 和 Chrome 现在默认处理这个问题。只需像往常一样添加widthheight 属性。详情请见this blog post


    更新 1:(2018 年 7 月)

    我发现了一个更聪明的替代版本:http://cssmojo.com/aspect-ratio-using-custom-properties-and-calc/。这仍然需要一个包装器元素,并且需要 CSS 自定义属性,但我认为它更优雅。 Codepen 示例是 here(感谢 Chris Coyier 的 original)。


    原文:

    来自this blog post by Jonathan Hollin:将图像的高度和宽度添加为内联样式的一部分。这会为图像保留空间,防止图像加载时重排,但它也是响应式的。

    HTML

    <figure style="padding-bottom: calc((400/600)*100%)">
      <img src="/images/kitten.jpg" />
    </figure>
    

    CSS

    figure {
      position: relative;
    }
    
    img {
      max-width: 100%;
      position: absolute;
    }
    

    figure 可以替换为div 或您选择的任何其他容器。此解决方案依赖于具有pretty wide browser support 的 CSS calc()。

    工作中的 Codepen 可见here

    【讨论】:

    • 如果浏览器对css attr() 的支持得到改善,我们可以通过将宽度和高度添加为数据属性而不是使用内联样式来进一步整理。
    • +1 代表潜在的未来attr()(不需要内联样式),但除此之外,这与以前相同(只是更适合手动编写,因为您不需要必须计算400/600 - 但在我的情况下,模板可以做到这一点)。
    • 对不起,当你说“这和以前一样”时,你指的是什么?我觉得我的答案与任何其他答案都不重复,它回答了这个问题。有什么办法可以改进吗?
    • 我的意思是,这是与以往相同的策略,但具有相同的缺点(内联样式)。这是一种不同的方法,但如果不能做到attr(height) / attr(width),就不是更好的方法。
    • 添加了使用 CSS 自定义属性的替代解决方案。
    【解决方案4】:

    首先,我想写下 2013 年 10 月的答案。这是不完整的复制,因此不正确。不要使用它。为什么?我们可以在这个sn-p中看到(将执行的sn-p滚动到底部):

    $('img').each(function() { 
        var aspect_ratio = $(this).attr('height') / $(this).attr('width') * 100;
        $(this).wrap('<div style="padding-bottom: ' + aspect_ratio + '%">');
    });
    img { max-width: 100%; height: auto; }
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <div style="width:300px;border:1px solid red">
    <img width="400" height="300" src="data:image/png;base64,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"/>
    Some text
    </div>

    我们可以看到文字离底部很远。在这个例子中什么是不完整/不正确的?我将用纯 JavaScript 的正确示例来展示它(我们不需要为此下载 jQuery)。

    纯 JavaScript 的正确示例

    请将执行的sn-p滚动到底部。

    var imgs = document.querySelectorAll('img');
    for(var i = 0; i < imgs.length; i++)
    {
        var aspectRatio = imgs[i].getAttribute('height') /
                          imgs[i].getAttribute('width') * 100;
    
        var div = document.createElement('div');
        div.style.paddingBottom = aspectRatio + '%';
        imgs[i].parentNode.insertBefore(div, imgs[i]);
        div.appendChild(imgs[i]);
    }
    .restrict-container div{position:relative}
    img
    {
        position:absolute;
        max-width:100%;
        top:0; left:0;
        height:auto
    }
    <div class="restrict-container" style="width:300px;border:1px solid red">
        <img width="400" height="300" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAZAAAAEsCAIAAABi1XKVAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAf3SURBVHhe7do9chtXGoVhb2Ryr0TllSjwLpx7CY6cusrZBFqAEydegPMpL2NEUhTvPf0HkBBxDDxVT6BXajbB7r5fNyB+992v/wD8O2QD1MoGqJUNUCsboFY2QK1sgFrZALWyAWplA9TKBqiVDVArG6BWNkCtbIBa2QC1sgFqZQPUygaolQ1QKxugVjZArWyAWtkAtbIBamUD1MoGqJUNUCsboFY2QK1sgFrZALWyAWplA9TKBqiVDVArG6BWNkCtbIBa2QC1sgFqZQPUygaolQ1QKxugVjZArWyAWtkAtbIBamUD1MoGqJUNUCsboFY2QK1sgFrZALWyAWplA9TKBqiVDVArG6BWNkCtbIBa2QC1sgFqZQPUygaolQ1QKxugVjZArWyAWtkAtbIBamUD1MoGqJUNUCsboFY2QK1sgFrZALWyAWplA9TKBqiVDVArG6BWNkCtbIBa2QC1sgFqZQPUygaolQ1QKxugVjZArWyAWtkAtbIBamUD1MoGqJUNUCsboFY2QK1sgFrZALWyAWplA9TKBqiVDVArG6BWNkCtbIBa2QC1sgFqZQPUygaolQ1QKxugVjZArWyAWtkAtbIBamUD1MoGqJUNUCsboFY2QK1sgFrZALWyAWplA9TKBqiVDVArG6BWNkCtbIBa2QC1sgFqZQPUygaolQ1QKxsu5ref/vef/z775Y8/FxvAmbLhYgwsLi377n3/x4evayxW2g9/PeRPn6bt2WZgcWnZd2w5qgYfPn76+ZenP//98/eLrwXeQ/a92p1W4ccfFl8OvIfs+/Tpx3EkxZuXp3eCAwMLriT7Lo0jaf0jqmmiGVhwJdn36M+Pfz8Po83Pp4ZtDgfW78+fdr348PH3xWYrz26fx+X4jZ5fT+zwhA/Rlnveeg2XNn3QPtl+2d/kOMxPzYNzjsPqTv76bf3HfPj7xR6ueS5uUfY9OmkYvVx22+vk8IOw+fFtXpPn2brit+fFs2/7v3WbY2LnuF34OJz2ceTRyNj5QbbkD3jtc3GTsu/SdA/cuE9+vb1v/FrDyatuuKzX7r0nW67/09fY9sx9s8s8YZ3h9cdh8+Z0zv/ADMYrp+Jc3KLs+7TyJu68u18sufjaXAAxE+Pi/vKvOQGfBuWwq/kZIVdIrsYcCltz+cKGn+JwZV7kOBw5vjmtv4wna7el5U5Kz8VNyL5bazNrsPu51XSBbm05PXpMj2njlw/X7nhZv2w/bDzsZNr55qidf8bpNXwrrx1YrzwOp9h/Sdun6dnB7af3XNyE7PuWt76FtQtrvOvu3u3Ha3RcKhtrb3gxwxBc3Xhjqa8Yt3yPNyOvHFivPA6nWd/ho3EYbT9iz89ZccB7z8VNyOZR3kUHeR2PY2j/Ap2WyjDa3rxQhy3PsvUweEHXHFg7J/FZHoGdWTYZZ8180ovPxU3IZkV8kLz54dHxrX5147cu1PmGf4bzPv15lesMrJOnRoyJk1/t5l2q+VzchGw2bL5Z2F05aXXjty5UA+tl48XdZZ+B9W+TfYeeL77tzyyeDCthvEaHlXO0h2nqXW5gTQ8U8+q9unceWDkvVs/I+g6P/mkyfPedt4Rl5+ImZN+fU6/RrYE13dJP3sPx2jtjoU4f1hzOhXf1vgNrfPDZPhc7Z3zzOXoyj8V5YBWfi5uQfX/GW+LOI9LOZtM1urlOprcq0x7evlDnnccSSl/3sL/ZZbzvwNrYw+joZE1HcnUn8x6Wh7H2XNyE7PszTqIneZlO9+3Plh83HLwTyUs8lu7bF+r894+WL3JeSOvbXNzVBtZiGOU5WtvmURzJaZSs7WQ5a0rPxU3Ivj/LgbVv4ylseQlueVkkW9/6aQUu/vXxC3MxvCzXHIvH1pbrG5z/Ar4czAseh3PP5hfzMD3vB1l7OLr6ubhZ2ffn6yX+efEcXe4Ht8HD1TIPu9V7/qPHNbDc28OaXCzUacHkw+COi6+Q7R9nx8OkuPBx2D8LG2d5cWaX+9+yNrAeXPNc3K7sO/Tlwnq5aNZuj+dcUmvX+tfnoNHW0nrFk8XsYAR8Iw1PWM+WR+BlJK18u623qyun8mk/wwP1wSG9zrm4WdnAsdMHFheVDRwzsK4kGzgyvvldfbPPt5IN7Jo+qjv8XQ0uKxt4tPVfAQO/PPXusoEHh79YZ1pdQzbwaOe3NHxudTXZALWyAWplA9TKBqiVDVArG6BWNkCtbIBa2QC1sgFqZQPUygaolQ1QKxugVjZArWyAWtkAtbIBamUD1MoGqJUNUCsboFY2QK1sgFrZALWyAWplA9TKBqiVDVArG6BWNkCtbIBa2QC1sgFqZQPUygaolQ1QKxugVjZArWyAWtkAtbIBamUD1MoGqJUNUCsboFY2QK1sgFrZALWyAWplA9TKBqiVDVArG6BWNkCtbIBa2QC1sgFqZQPUygaolQ1QKxugVjZArWyAWtkAtbIBamUD1MoGqJUNUCsboFY2QK1sgFrZALWyAWplA9TKBqiVDVArG6BWNkCtbIBa2QC1sgFqZQPUygaolQ1QKxugVjZArWyAWtkAtbIBamUD1MoGqJUNUCsboFY2QK1sgFrZALWyAWplA9TKBqiVDVArG6BWNkCtbIBa2QC1sgFqZQPUygaolQ1QKxugVjZArWyAWtkAtbIBamUD1MoGqJUNUCsboFY2QK1sgFrZALWyAWplA9TKBqiVDVArG6BWNkCtbIBa2QC1sgE6/frP/wEiNOVSBSWikgAAAABJRU5ErkJggg=="/>
        Some text<br>
        <img width="400" height="300" src="data:image/png;base64,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"/>
        Some text
    </div>

    2013 年 10 月的回答中的错误:图像应该绝对 (position:absolute) 放置到被包装的容器中,但它不是这样放置的。

    我对这个问题的回答到此结束。


    如需了解更多信息,请阅读更多信息

    【讨论】:

    • 是的,position: absolute 从那个答案中消失了。其余的与问题无关,抱歉。
    • @Ry-,为什么这无关紧要?为什么我的答案是“-1”?至少我用纯 JS 编写了正确的版本。这不公平!
    • 你不明白为什么“使用 HTML5 我们可以做不同的事情”之后的所有内容都无法解决问题?
    • @Ry-,你是对的,这句话是错误的,但我的意思不同。我也不是以英语为母语的人。我根据这句话改变了我的答案。我希望现在我的回答完全OK?
    • @Ry-,你的意思是我应该删除句子“This is the end my answer to this question”之后的所有文字吗?
    【解决方案5】:

    如果我理解要求,您希望能够设置图像大小,该大小仅在内容 (HTML) 生成时才知道,因此可以将其设置为内联样式。

    但这必须独立于 CSS,并且在图像加载之前,所以也独立于这个图像大小。

    我找到了一个解决方案,将图像包装在一个 div 中,并在这个 div 中包含一个 svg,可以将其设置为直接作为内联样式具有比例。

    显然这不是很语义,但至少它有效

    包含的 div 有一个名为 img 的类,以表明它应该是一个 img

    为了尝试重现加载阶段,图像的 src 已损坏

    .container {
      margin: 10px;
      border: solid 1px black;
      width: 200px;
      height: 400px;
      position: relative;
    }
    
    .img {
      border: solid 1px red;
      width: fit-content;
      max-width: 100%;
      position: relative;
    }
    
    svg {
      max-width: 100%;
      background-color: lightgreen;
      opacity: 0.1;
    }
    
    #ct2 {
      width: 500px;
    }
    
    .img img {
      position: absolute;
      width: 100%;
      height: 100%;
      max-height: 100%;
      max-width: 100%;
      top: 0px;
      left: 0px;
      box-shadow: inset 0px 0px 10px blue;
    }
    <div class="container" id="ct1">
        <div class="img">
            <svg xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="xMinYMin meet" viewBox="0 0 400 300" width="400">
            </svg>
          <img width="400" height="300" src="missing.jpg">
        </div>
    </div>
    <div class="container" id="ct2">
        <div class="img">
            <svg xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="xMinYMin meet" viewBox="0 0 40 30" width="400">
            </svg>
          <img width="400" height="300" src="missing.jpg">
        </div>
    </div>

    【讨论】:

    • 是的,具有相同尺寸的内联 SVG 的总体思路可能是最可靠和最灵活的方式。谢谢。
    【解决方案6】:

    我发现最好的解决方案是创建一个具有相应尺寸的透明base64 gif作为img标签的占位符,在页面加载后通过js触发加载。

    <img data-src="/image.png" src="data:image/gif;base64,R0lGODlhyAAsAYABAP///wAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==">
    

    对于博客文章等,我使用这个 PHP 函数来自动创建它们

    function CreatePreloadPlaceholderGif($width, $height) {
        $wHex = str_split(str_pad(dechex($width), 4, "0", STR_PAD_LEFT), 2);
        $hHex = str_split(str_pad(dechex($height), 4, "0", STR_PAD_LEFT), 2);
        $hex = "474946383961".$wHex[1].$wHex[0].$hHex[1].$hHex[0]."800100ffffff00000021f904010a0001002c00000000010001000002024c01003b";
        $base64= '';
        foreach(str_split($hex, 2) as $pair){
           $base64.= chr(hexdec($pair));
        }
        return base64_encode($base64);
    }
    echo CreatePreloadPlaceholderGif(300, 500);
    //  R0lGODlhLAH0AYABAP///wAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==
    

    在前端,结果是这样的

    function loadimage() {
          elements = document.querySelectorAll('img[data-src]');
        elements.forEach( el => {
            el.setAttribute('src', el.getAttribute('data-src'))
        });
    }
    img {
      background-color:#696969;
    }
    <div>300x500 image placeholder</div>
    <img data-src="https://albahaabazar.com/wp-content/uploads/2017/11/300x500.png" src="data:image/gif;base64,R0lGODlhLAH0AYABAP///wAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==">
    <div>After page load, run js command to replace src attribute with data-src</div>
    <button onclick="loadimage()">Load image</button>

    【讨论】:

      猜你喜欢
      • 2012-03-01
      • 2014-06-21
      • 2016-12-25
      • 1970-01-01
      • 2010-12-17
      • 1970-01-01
      • 1970-01-01
      • 2012-04-14
      • 1970-01-01
      相关资源
      最近更新 更多