HTML5教程之响应式图片解决方案
如今开发一个网站不是响应式都不好意思拿出来,那么作为响应式中的重要一环「响应式图片」你又是如何解决的呢?
网站的平均加载已经到了近 2MB 并在不断地增加中,其中图片占据了绝大多数流量(63%)。可以肯定的是网页已经有了严重的大小问题,而图片就是罪魁祸首。虽然已经有很多种 措施 可以减少网页加载量,但或许更重要的步骤之一是确保响应式图片的加载方案。通过利用响应式图片解决方案,我们可以确保最佳的图片被加载,带宽不会被过大的图片所浪费。因此 W3C 定义了 picture 标签:基于检测客户端设备类型的可替换图片方案。具体是由 picture 这个标签去实现,也就是说我们现在有了一个基于标准的响应式图片解决方案可以用在实践中。
长话短说(人话)
? 断点(breakpoints)应该 取决于内容 而不是设备宽度 (CSS3 media query) 根据尺寸加载不同图片
计算图片像素密度并加到图片加载列表中
通过消除图片加载列表中太相近的值来让加载列表变得可维护 利用程序自动输出图片的不同大小
利用 img 标签的 srcset sizes 等属性输出同一张图片的不同路径/尺寸,以解决响应式图片的大小和像素密度的问题
?
?
?
?
?
? Picturefill 库能让我们现在就使用这些强大的特性
? 虽然 Picturefill 还有一些缺点 但这么做仍然利大于弊
查看DEMO
定义
第一步就是定义所有响应式图片的尺寸和断点,这些信息在网页原型中就应该被精确的标示出来。重要的一点是 你的断点应该取决于你的内容 而不是不同设备的宽度。这么做是因为设备的参数是在不断变化的,流行的设备尺寸总是在变。通过让内容来决定断点位置,这将确保我们的界面在所有屏幕上响应而不是特殊的几个设备。
注意 当决定哪些图片应该被做成响应式时,要记住一点,大多数都是放在内容中的图片。例如在 HTML 中插入的图片而不是在 CSS 中的背景图片。
图片尺寸
首先将你的浏览器窗口放到最大(或者你规定的内容展示最大宽度),然后记录下此时你的内容宽度和你想要展示的图片宽度,通过浏览器的开发者工具或者类似的插件。
接下来缩放你的浏览器窗口直到你想要给图片设置宽度的下一个断点,再继续缩放直到你记录下所有的作用于图片宽度断点。当你完成的时候你应该记录下每张图片在不同大小下应该载入的宽度。
举例,仅仅是例子:
[max-width]:[1440][breakpoint large]:[1120][breakpoint medium]:[800][reakpoint small]:[400]
注意 关于决定断点需要注意的是:断点越多,代码越难维护。除此之外大量的断点会使 CSS 变得臃肿。所以尽量在保证效果的情况下保持最少的断点。
高分辨率
下一步是根据你想要支持的分辨率 对图片宽度进行计算。决定要支持那些分辨率是很困难的,因为有 太多的不同的分辨率,并且每支持一种分辨率你需要计算宽度并放在你的图片加载列表里。所以需要做的是根据实际情况和你的用户群体去选择支持不同的分辨率。
如果你已经决定了需要支持那些高分辨率,那图片加载列表会像下面这样:
[max-width]:[image width],[image width x1.5],[image width x2][breakpoint large]:[image width],[image width x1.5],[image width x2][breakpoint medium]:[image width],[image width x1.5],[image width x2][breakpoint small]:[image width],[image width x1.5],[image width x2]
整合
如你所见,我们的图片列表数量会随着支持不同的分辨率和断点而变长。通过改变整合列表项让列表更清晰可控是很有必要的。例如任何相近或者不超过 200 像素差距的值。将几个相近的值整合为一个值将有助于构建更清晰的列表:
(min-width:1280px):1040px,1560px,2080px(min-width:1120px):924px,1386px,1848px(min-width:800px):800px,1200px,1600px(min-width:400px):400px,600px,800px
注意 这里用像素来做断点值只是为了好对应图片宽度,实际上你的 断点应该使用相对单位(em/rem not px)
输出
现在我们有了一个慎重考虑的图片宽度列表,下一步则要将每个图片导出为以「断点名」+「像素密度倍数」为名的文件。例如我将最大的断点称为 “large” 并且图片像素密度倍数为两倍,那么我的文件名则为 ‘image_large@2x.jpg’。我倾向于在 Photoshop 中保存图片为 70% 压缩,因为 70% 压缩能确保达到最优的图片大小并且不会损失过多的清晰度(这取决于不同图片,目的是在保证清晰度的情况下尽量减小文件大小)。如果你倾向于保存为 JPEG 格式,那确保通过勾选 progressive(渐进) 来让图片从模糊到清晰的加载效果。
译者注 PS/AI 中保存图片请使用「存储为 web 格式/save for web」,快捷键 ctrl/command + shift + alt + s。PNG 格式请勾选 交错/interlaced,JPEG 格式请勾选 渐进/progressive。
脚本
通过提前写好动作脚本(宏)可以让你批量自动化导出你想要的图片大小。根据你选择的设计软件,自动化的脚本可以很容易的设置使用。不幸的是你仍然需要手动重命名每张图片为 ‘xxx_large@2x.png’ 这样的命名格式。如果你使用 Photoshop 这里有一个 指南 可以帮助你编写你自己的脚本批处理。或者你也可以用这个 写好的 PS 脚本。
构建工具
另外一个自动化导出图片的方法是使用构建工具,我选择使用 Gulp。Gulp 是一个基于 Javascript 流式思想的构建工具,这使得构建复杂任务的编写更加简单。这里有各种任务插件,包括调整图片大小、文件重命名。只需要编写小段配置,你就可以完全自
动化工作流中的某些部分,并且在使用的时候你无须再考虑。使用构建工具的另一个好处是你可以将你的任务链式的串联起来并且可调整顺序。
优化
最后,你需要注意的是在将你的图片放进网页前进行优化。这将确保图片数据多余的数据被删除,将有效的减小文件的大小。和处理图片或缩放图片一样,有很多种方法可以完成这个任务:你可以使用软件或者终端命令手动优化图片,或者你也可以使用构建工具自动完成这项任务。我喜欢的 JPGs 图片压缩软件是 imageOptim PNG 是 imageAlpha,还有一大堆软件你可以选择。
另外你也可以使用强大的构建工具,好处你不需要记得压缩图片,你只需要在你的每个项目里区配置工具即可。我选择用 Gulp 的插件
(imagemin)[https://www.npmjs.com/package/gulp-imagemin] 来做这件事情,它也能压缩 SVG 和 GIF 文件。
实现
最终的步骤是在网页中实现响应式图片。这种方法即所谓的 分辨率切换,因为我们只是切换了同一张图片在不同尺寸和分辨率下的源文件地址,以达到在不同的尺寸和像素密度下达到响应的目的。所以我们会使用 picture 标准的一部分 srcset 和 sizes 属性。这些属性继承了