假设您在 <img>
中使用了一个 800×600 像素的图像。它真的会在您的网站上显示为 800px 宽吗?这很可能不会。我们倾向于将图像放入灵活的容器元素中,并且内部图像设置为 width: 100%;
。因此,该图像最终可能为 721px 宽,或 381px 宽,或任何宽度。不会改变的是该图像的纵横比,除非您将其尴尬地压缩(忽略特殊用例 object-fit
场景)。
要点是我们不知道图像加载之前将占用多少垂直空间。这就是卡顿的原因!可怕的卡顿!它无处不在,而且很糟糕。
更新!这实际上发生了。所以您只需在图像上放置正确的自然宽度和高度属性,它们就会在没有卡顿的情况下加载,即使 CSS 使图像具有流动性。所以像这样操作:<img src="image.jpg" width="800" height="600">
现在有方法在 HTML/CSS 中创建 纵横比大小的盒子。没有一个选项特别优雅,因为它们依赖于设置零高度并使用填充推动盒子高度的“技巧”。如果有一个平台功能可以帮助我们解决这个问题,岂不是更好?我所知的第一个解决此问题的尝试是 intrinsicsize
属性。Eric Portis 在 流畅的图像加载 中写道了它是如何完美地工作。
我们将得到以下内容
<img src="image.jpg" intrinsicsize="800x600" />
这目前在 Chrome 71+ 中 处于实验阶段,它确实有助于解决此问题。
但是……
intrinsicsize
属性是全新的。它仅在开发人员了解并注意实施它的网站上才有帮助。而且它很棘手!图像往往是任意大小的,并且每个图像都需要自定义 intrinsicsize
属性才能准确并发挥其作用。也就是说,如果它根本能从标准中脱颖而出的话。
还有另一种可能性!Eric 还谈到了 CSS 中的 aspect-ratio
属性作为一种潜在的解决方案。它也仍然 只是一个草案规范。您可能会说,但这有什么用?它需要像 intrinsicsize
一样定制,这意味着您必须将其作为内联样式才能发挥作用。如果它能解决一个大问题,也许这还不错,但内联样式很难覆盖,而且 HTML 属性方法似乎更符合图像的精神。想想 srcset
如何提示浏览器可下载哪些图像,允许浏览器为该场景选择最佳图像。提前告诉浏览器 aspect-ratio
同样有用。
我从 Jen Simmons 那里了解到了一种处理此问题的绝佳方法:根据元素现有的 width
和 height
属性,将默认纵横比放入 UA 样式表中。 如下所示
img, video {
aspect-ratio: attr(width) / attr(height);
}
仔细想想。
现在,如果您已经拥有
<img src="image.jpg" width="800" height="600" />
它会在页面加载时自动具有正确的纵横比。这太棒了。
- 它易于理解。
- 互联网上有很多网站已经在其图像上设置了这些属性。
- 新开发人员将毫不费力地理解这一点,而老开发人员会很高兴这里几乎(如果有)不需要做任何工作。
我喜欢 CSS 功能的想法。但我更喜欢将其放入 UAUA 样式表中的想法——这不是一件小事——我没有资格理解其中的所有含义——但乍一看,这感觉是一件非常棒的事情。
Jen 已发布了一个问题,供人们发表他们的想法,并链接到 Firefox 将在其中测试此功能以查看其效果的错误问题。
如何将
height
属性与响应式图像结合使用?如果它具有内联高度,我认为您只有一个选项。“height: auto !important;”
我想所有这些都是为了防止图像加载时发生回流。
我完全赞成新功能,所以请同时为我们提供新的图像“intrinsicsize”属性(在“img”元素上)和 CSS 中的“aspect-ratio”属性,谢谢。
但是,我不确定我是否理解为什么“aspect-ratio”CSS 属性只能用作放置在 HTML 中的内联样式。
浏览器在读取 CSS 后不会绘制页面,然后将这些样式应用于元素吗?我的想法是,您不能只将每个图像包装在一个“div”或“figure”中,并在外部样式表中为其设置一个 aspect-ratio 属性,然后让图像使用
object-fit: cover;
填充其容器吗?所以假设我们所有的图像都包装在一个具有“gallery-image”类的 div 中,我不能在外部样式表中编写以下内容吗?
……然后浏览器只需绘制一堆 16/9 纵横比的框并用其中的图像填充它们?
显然,还需要额外的布局代码来创建图像的网格或行……但我认为所有这些都可以在外部 CSS 文件中工作。
多年来,自从响应式网页设计成为一项功能并且我们的图像在很大程度上具有流动性以来,我也没有在“img”元素中包含“width”和“height”属性。
真的希望 aspect-ratio CSS 能实现。我现在一直在使用 %padding-bottom 作为响应式纵横比的解决方法。
顺便说一句:对于非英语母语人士来说,“intrinsicsize”这个词绝对糟糕。为什么不用“ratio”或其他词呢……
您还可以使用自定义属性为图像添加纵横比,而无需定义固定高度属性。
示例
HTML
img src=”https://via.placeholder.com/3/4″
style=” –image-width: 800px;” alt=””
CSS
img{
width: var(–image-width);
height: calc(var(–image-width)*3/4);
}
公式:height = width * aspectratio(例如 16/9、3/4、8/5 等)
Codepen
img {
max-width: 100%;
height: auto;
}
不必复杂。
那么在该图像加载之前,浏览器应该为任意图像保留多少垂直空间?
它不知道,因此会卡顿。
但您是对的,它不必复杂,请查看上面的文章。
您需要该 CSS和img 元素中的宽度和高度属性。后者似乎很烦人,但您在使用 intrinsicsize 时也已经这样做了……但是的,我可以确认它确实有效(max-width: 100% 覆盖了宽度,而 height: auto 依赖于 img 的属性来确定要使用的实际高度)。
为什么我们不直接实现
<amp-img>
并使用其内置工具来实现这一点呢?没人这么说。
我也将每个 img 包裹在一个带有纵横比作为内联样式的 div 中。
:root {
--main-width: 60vw;
}
.gallery-image {
width: var(--main-width);
height: calc(var(--main-width) * var(--aspect-ratio));
}
.gallery-image img {
width: 100%;
height: auto;
}
来自 https://css-tricks.cn/the-complete-guide-to-lazy-loading-images/ 的分叉笔
实际上不需要任何 SVG 字符串的编码。这是有效的
src=”data:image/svg+xml,”
很棒的文章,最后还有一个超级快速的解决方案。我们无论如何都应该在图像上设置宽度和高度属性,所以这很酷。但我有点困惑。您能否举一个想要了解图像将占据多少垂直空间的用例?
嗨,Kevin,
假设您点击某个文档的链接,该链接将您直接带到页面中间的锚点标签。
当您当前位置上方的图像加载时,它们会将内容向下移动。
使用文章中描述的技术,浏览器将能够保留正确的垂直空间并防止这种偏移。