自从互联网适应性出现以来,就出现了显示图像的问题。 我们希望该网站在任何平板电脑,手机,纵向或横向屏幕方向以及超大型5K显示器上都看起来不错。 市场上也有高像素密度(DPI)的Retina显示器,其中常规图像看起来很模糊。 移动流量的份额正在增长,并且大量资源旨在经济地加载图像。 让我们看看他们如何在Apple,Tilda和博客平台Medium的网站上解决这些问题。
苹果:背景图像高级用户
苹果公司依靠其产品的设计,着重于图像显示研究。 在苹果网站上(在撰写本文时),CSS功能(更确切地说是背景图像)提供了图像优化。 这种方法的关键原理是断点之间的图像宽度固定,即拒绝“橡胶”图像。 考虑来自网站
www.apple.com/mac的图像之一的示例
<figure class="imac-image" data-progressive-image=""></figure>
.section-imac .imac-image { width:939px; height:631px; background-size:939px 631px; background-repeat:no-repeat; background-image:url("/v/mac/home/af/images/overview/hero/imac__dlz2ciyr6hm6_large.jpg"); } @media only screen and (-webkit-min-device-pixel-ratio: 1.5), only screen and (min-resolution: 1.5dppx), (-webkit-min-device-pixel-ratio: 1.5), (min-resolution: 144dpi) { .section-imac .imac-image { background-image:url("/v/mac/home/af/images/overview/hero/imac__dlz2ciyr6hm6_large_2x.jpg") } } @media only screen and (max-width: 1068px) { .section-imac .imac-image { width:795px; height:536px; background-size:795px 536px; background-repeat:no-repeat; background-image:url("/v/mac/home/af/images/overview/hero/imac__dlz2ciyr6hm6_medium.jpg") } } @media only screen and (max-width: 1068px) and (-webkit-min-device-pixel-ratio: 1.5), only screen and (max-width: 1068px) and (min-resolution: 1.5dppx), only screen and (max-width: 1068px) and (min-resolution: 144dpi) { .section-imac .imac-image { background-image:url("/v/mac/home/af/images/overview/hero/imac__dlz2ciyr6hm6_medium_2x.jpg") } } @media only screen and (max-width: 735px) { .section-imac .imac-image { width:365px; height:246px; background-size:365px 246px; background-repeat:no-repeat; background-image:url("/v/mac/home/af/images/overview/hero/imac__dlz2ciyr6hm6_small.jpg") } } @media only screen and (max-width: 735px) and (-webkit-min-device-pixel-ratio: 1.5), only screen and (max-width: 735px) and (min-resolution: 1.5dppx), only screen and (max-width: 735px) and (min-resolution: 144dpi) { .section-imac .imac-image { background-image:url("/v/mac/home/af/images/overview/hero/imac__dlz2ciyr6hm6_small_2x.jpg") } }
为了实现跨浏览器的兼容性,立即使用三种方法来设置屏幕像素密度:
-webkit-min-device-pixel-ratio:1.5
最小分辨率:1.5dppx
最小分辨率:144dpi
这种方法的优缺点是什么?
优点
- 易于实施。 这也许是将图像更改为特定尺寸和屏幕密度的最容易理解的方法。
- 涵盖所有问题:屏幕尺寸和像素密度问题已得到解决。
- 预先确定的尺寸使布局无跳跃。
- 您可以使用内置的CSS功能处理背景(混合模式用于效果,位置-必要时裁剪图像)。
缺点
- 您无法制作“橡胶”照片。 固定尺寸决定了宽高比,因此当您尝试压缩或拉伸时,我们将裁剪图片或下面有空白区域。 是的,您可以按百分比而不是大小使用padding-bottom,但这已经是一个变通方法,CSS hack使基本概念变得复杂。
- 很多CSS代码。 是的,CSS易于阅读,但是具有大量的断点和图像,CSS的大小可以无限地增加(请参阅下面的“用于救援的CSS预处理器”)。
- 无法控制下载图像。 如果以纯格式使用此方法,则将同时加载页面上的所有图片。 而且CSS与img不同,它没有onload回调,可让您控制是否加载图片。
- 需要精确的精度。 您将必须为所有图片设置尺寸。 同样重要的是,当将一个图像替换为另一个图像时,您将需要为新尺寸编辑CSS。
CSS预处理器进行救援
您很可能已经在使用CSS预处理器之一,例如SCSS,LESS,PostCSS或Stylus,它们可以极大地简化您的生活。 让我们尝试使用SCSS从Apple网站优化代码。 对于媒体表达,请使用
媒体混合器并为图片编写我们的混合器:
@mixin image($width, $height, $url) { width: $width; height: $height; background-size: $width $height; background-repeat:no-repeat; background-image:url($url); }
让我们设置变量:
$breakpoints: ( 'phone': 735px, 'tablet': 1068px ); $media-expressions: ( 'screen': 'only screen', 'retina': '(-webkit-min-device-pixel-ratio: 1.5), (min-resolution: 1.5dppx), (min-resolution: 144dpi)' );
我们得到了可以在Apple的CSS中进行一对一编译的SCSS:
.section-imac .imac-image { @include image(939px, 631px, "image_large.jpg"); } @include media('screen', 'retina') { .section-imac .imac-image { @include image(939px, 631px, "image_large2x.jpg"); } } @include media('screen', '<=tablet') { .section-imac .imac-image { @include image(795px, 536px, "image_medium.jpg"); } } @include media('screen', '<=tablet', 'retina') { .section-imac .imac-image { @include image(795px, 536px, "image_medium_2x.jpg"); } } @include media('screen', '<=phone') { .section-imac .imac-image { @include image(365px, 246px, "image_small.jpg"); } } @include media('screen', '<=phone', 'retina') { .section-imac .imac-image { @include image(365px, 246px, "image_small_2x.jpg"); } }
总结
如果您没有很多图片或图片很少更改,这是一种很好的居住方式。
Tilda:具有模糊效果的背景图像
Tilda是一个站点构建器,提供了用于显示图像的各种组件。 考虑“懒”上传图片的最简单方法。 在加载图片之前html是什么样的:
<div data-original="https://static.tildacdn.com/image.jpg" style="background: rgba(0, 0, 0, 0) url(https://static.tildacdn.com/image-small.jpg) no-repeat scroll center center / cover;"> </div>


由于预览很小(20x20像素),因此可以实现模糊效果,但是使用封面的css属性,可以将图片拉伸到整个宽度和高度。 缺点:这种模糊看起来不太好,但是非常简单,不会使处理器过载。
加载后,完整尺寸的图像将直接替换为内联样式。
优点
- 延迟加载。
- 易于维护。
缺点
- 任何设备的图片相同。 适应性仅在样式限制内实现(图片仅以不同方式裁剪)。
- 丑陋的模糊效果。
- 在模糊和全分辨率之间没有过渡。
总结
如果您只需要一个简单的组件并且不想为不同的屏幕分辨率使用六张或更多图片,这是一种有效的方法。 非常适合包含大量图片的网站。
中:画布模糊
medium.com博客平台由于欠载图像的美丽模糊效果而在网络图像领域产生了很大的变化。 使用stackblur-canvas库可以实现此效果。


HTML看起来像一个三明治:
<img src="placeholder.jpg"> <canvas> <img src="full-size.jpg">
这使您可以实现平滑过渡的效果。 对于全尺寸图片,最初的不透明度:0经过CSS过渡到不透明度:1。
模糊战:CSS vs SVG vs Canvas
因此,如果我们不是Apple,最有可能使用延迟加载图片和模糊效果会更方便。 目前,至少有三种方法可以创建布莱尔效应(这是蒂尔达的另一种选择,但我们不会考虑,因为这不是“真正的”布莱尔)。
如果您已经在CSS浏览器中内置了模糊过滤器,为什么值得使用stackblur-canvas进行模糊处理呢?
- 问题。 默认情况下,CSS和SVG滤镜会模糊图像的边缘。 对于svg过滤器,有一个特殊的解决方案 ,对于内置过滤器:blur()必须使用裁切。
- 性能表现 Stackblur画布的工作速度非常快,css滤镜的工作速度甚至更快,因此对于大量模糊图像,绝对是css滤镜的选择。
- 美人 在主观上,但是在我看来,stackblur看起来更漂亮。 svg过滤器具有丑陋的伪影。
图片标签-进化的顶峰
在一开始,我们描述了Apple方法,发现CSS具有用于屏幕尺寸和像素密度的媒体表达式。 并且可以同时使用它们来选择要显示的特定图片。 一个重大的缺点是,背景上的图片不“知道”其宽高比,而不能是“橡胶”。 另外,从网络语义的角度来看,使用背景对于连续显示所有图像是不正确的。
img标签可能具有srcset属性,但是您必须选择屏幕尺寸或像素密度-您不能组合这些参数。
图片标签没有这个缺点,并且像img一样,它“知道”其纵横比。 已经有
92%的浏览器支持它。 该标签适用于那些负担不起不适应IE的用户。
交叉口观察者API
最后,让我们谈谈延迟加载图片的实现。 经典方法是结合使用滚动,调整大小和方向更改事件,并计算特定图片相对于屏幕可见区域的位置。
在2019年,您可以使用特殊的浏览器API-
交叉观察器替换拐杖组。 所有现代浏览器都支持它。 对于较旧的iOS和IE,您应该使用官方的
w3c polyfill 。
展望未来:完全幸福还缺少什么
因此,我们已经有了一个图片标签,该标签具有良好的浏览器支持,但是仍然存在延迟加载的问题。 我们仍然需要依靠我们自己的基于交集观察器或JS事件组合的实现。 浏览器何时会提供本机解决方案? 例如,Chrome 75版承诺为img和iframe标签的loading属性提供支持。 您可以通过检查图片原型中属性的存在来为本地支持延迟加载更新组件:如果成功,则可以拒绝自己的延迟加载代码,因为一切将由浏览器完成!
if ('loading' in HTMLImageElement.prototype)
CMS和用户内容
显示用户上传的图像的最佳方法是什么? 通常,值得做的是尽可能简单,而不必强迫他分别为手机,平板电脑和台式机上传图片。 因此,对于所有设备,我们只有一张图片。 在这种情况下,Tilda(为了最大程度地简化)或Medium方法是完美的-如果您想产生真正的模糊效果,也许用标准的CSS代替stackblur-canvas:blur()以获得更高的性能。
总结
仍然没有单一的“最正确”的方式来显示图片。 如果您需要支持较旧的浏览器和IE,那么您可以选择带有媒体表达式和img的背景图片(用于简单情况)。 对于新项目,将背景图像替换为图片可能更方便。 如果要进行漂亮的延迟加载,请尝试使用stackblur-canvas,如果性能对您很重要,请在波浪号样式的背景上使用CSS滤镜或拉伸的图片。