响应式设计(五)

响应式图片


图片平均消耗 60% 以上的字节数来打开网页,但“网络中”大多数字节数用于视频。

在这章中,你将用到 Google ChromeChrome开发者工具

你可以用 Chrome开发者工具 快速得知你的网页在各种设备上的表现。当然,设备模拟器并不能真正代替在实际设备上的体验。为了在手机或平板设备上进行测试,你需要确保已经配置好了远程调试所需的环境。

比特和像素


Total bits = pixels x bits per pixel

照片等图片文件的大小,取决于 像素数 乘以 存储每个像素所需比特的数量。因此,为了提高网站性能,你要使用 尽可能小的图片尺寸 以及 尽可能高的图片压缩率

保存图片时的第一条原则是 用尽可能最低的质量和尽可能小的尺寸。不过,你该如何在保持图片质量的同时减少文件大小呢。

请求和盈利


更重要的是 平均每个网页发出 56个 请求以加载图片;每次请求对页面加载都是一项成本。

谷歌,亚马逊和其他公司的研究表明,即使是一个非常小的页面加载延误都可能造成明显的流量和经济损失。

相对大小


将图片的 max-width 设置为 100%,图片会很好的扩大,不过最大也只能放大到它的自然宽度。

如果想要两张图片(假设图片宽426px)并列对齐,无论视图区域的尺寸如何,该怎么做?简单,调整相对尺寸为50%的宽度。如果想要在两个图片之间加一个 10px 的边距,可以使用 margin-right: 10px; 也可以使用 calc,这是一个结合绝对值和相对值的好办法。比如,将百分比宽度与一个固定的边距组合

img {
margin-right: 10px;
max-width: 426px;
width: calc((100% - 10px) / 2);
}

横向和纵向


对于响应式设计来说,一个黄金法则就是 不要假设视图区域的尺寸一致保持相同

学习对于不同屏幕方向,如何使用 media queries

鲜为人知的CSS单位


你想要一张图片响应式铺满视图区域的整个高度吗?随意拿一张图片(宽512px,高384px;屏幕尺寸:800px x 612px)来测试一下。

你可能经常设置图片高度为 100%,不过这个只在 HTML 的高度下起作用。而且 body 元素得高度也同样被设置为 100%。

一个简单方法是使用 VH 单位,是视图高度的缩写。一个VH 单位对应着 1% 的视图高度。因而,100VH 对应着 100% 的高度。

img {
height: 100vh;
}

屏幕上测试图片比例为:816px x 612px

你可以同样使用 VW 视图宽度,你可以设置图片的宽度为 100VW ,等于 100% 的视图宽度。都是最大的。

img {
width: 100vw;
}

屏幕上测试图片比例为:800px x 600px

另一个常见的响应式用例是 当你想要调整图片尺寸去适应视图区域较小的高度或宽度,可以使用 vmin单位,对应着 1% 的宽度或高度,使得视图区域最小化。

img {
width: 100vmin;
height: 100vmin;
}

屏幕上测试图片比例为:612px x 612px

如果你想要一张图片铺满整个视图区域而不需要拉伸或收缩图片的话,可以使用 vmax单位,对应着 1% 的视图区域宽度或高度,都是最大的。

img {
width: 100vmax;
height: 100vmax;
}

屏幕上测试图片比例为:800px x 800px

是否注意到,将 heightwidth 设置为 100vmax100vmin 会如何改变图片的宽高比?它会将你的图片压缩成正方形,所以,如果你想要保留其宽高比,请小心!

光栅图(Raster)和矢量图(Vector)


有两种不同的基础方式去创建和存储图片,以及这会影响你如何响应式地部署图片:光栅图(Raster)和矢量图(Vector)。

光栅图 就是照片以及其他类型的图片以及单独颜色点所组成的网格。可能来源于照相机、扫描仪或者由HTML画布元素创建。

矢量图 就是比如商标和线条艺术的图片,可以由一组曲线、直线、形状、填充颜色和渐变所定义的。可以由 Adobe Illustrator 等类型的程序创建 Inkscape 或者 由 SVG一类的矢量格式。SVG 使得响应式矢量图像运用在网页中成为可能。

矢量文档格式优于光栅文档格式是浏览器可以渲染各种尺寸的矢量图片。毕竟,矢量图片格式描述了图片的几何形状,是由线条、曲线、颜色等组成,而非单独颜色点组成。矢量图片的缩放不会降低图片质量。

有一个很好的基本原则提高跨平台的图片性能,就是为相片使用JPEG格式,以及例如 Chrome 的浏览器也同样支持其他格式。例如 WebP 是一种可以提供更好的压缩比例和特性的图像格式,支持 alpha 有损动画处理以及无损压缩。

你可以为矢量图使用 SVG。对于 矢量图和纯色图,例如商标以及线条艺术,如果你不能使用 SVG 格式就使用 PNG 格式。优先选择 PNG 而不是 GIF 格式是因为前者有更多颜色,更好的压缩率以及没有版权问题。

压缩、优化和自动化

图像通常占据了网页上下载字节的大部分,通常也占据了大量的视觉空间。 因此,优化图像通常可以最大限度地减少从网站下载的字节数以及提高网站性能:浏览器需要下载的字节越少,占用客户端的带宽就越少,浏览器下载并在屏幕上渲染有用内容的速度就越快。

一个最著名的批量图片处理软件叫 ImageMagick,光栅图和矢量图都可以处理。它是一款免费的开源软件,它将你在平时基于GUI界面的图片处理软件中的操作自动化执行,比如转换图片格式、裁剪或者应用滤镜。对于响应式图片,这意味着 可以自动生成同一幅图片的多种版本,不同尺寸或格式。

你可以将图片自动优化工具融合进你的工作流:

图片处理工具:

我们怎样才能检查网页上的所有图片都被优化了呢?

现在这有一个很棒的检查图片的工具是 PageSpeed Insights。我们可以在开发者工具中使用它。

性能


现实中,移动网络的实际情况是 文件请求次数和请求文件的大小同样重要。也就是说,你需要减少请求图片的次数,而不仅仅是图片文件的大小。

性能是真正响应式设计的基本组成部分。在实践中,这意味着你需要减小文件大小的同时,还要减少请求文件的次数。一种减少图片数据的好办法是压缩图片或者减少图片的数量。

要减少图片下载次数,你也可以使用 CSS 图片精灵响应式精灵 。精灵页 图片组合了大量图片,这些图片可以通过将精灵页设置为元素背景,然后通过 CSS 调整背景位置来单独显示。此技巧对图标和其他重复图形尤为有用。

无论你采用何种技巧来避免延迟,都请注意 HTTP/2 带来的变化。

简单地说,HTTP/2 表示请求多个文件的成本更小:准备停止使用脚本编写、连接和其他 HTTP/1 技巧!

CSS 背景图片技巧


图片的尺寸会尽可能的小,但仍然会覆盖整个包含块:
background-size: cover; cover 属性确保包含块被完全填充,意味着某一个边的边长过长。

图片的尺寸会尽可能大,并保持在包含块中是完整可见的:
background-size: contain; contain 属性时,图片会完全被显示出来,意味着某一边长可能会小于包含块的边长

符号字符


避免使用图片并保持网站的响应性,如果需要图形标志,例如箭头、星星或者桃心,可以看看有无这样的字符。

Unicode 字符集
Unicode 符号集合

Unicode 字符真的非常厉害。它包含 110,000 个字符。
使用 Unicode 字符时,你需要确保 在 meta 标签中将 charset 属性值设为 utf-8。

<meta http-equiv="Content-Type" content="text/html;charset=utf-8">

更多关于 meta tag charsets 的信息

这是一个 unicode 符号的列表

查看 unicode 字符时遇到问题?很遗憾,并非所有浏览器默认情况下都能查看所有 unicode 字符所需的字体。此站点将帮助你确定你的浏览器可以呈现的字符。请参阅此处的一些建议,了解如何在 Windows 上通过 Chrome 启用 unicode。

图标字体


图标字体相比于图片有很多优点。它们是矢量的图形,可以被无限的缩放,并且整套图像可以以一种字体被下载,这使得它成为一种非常有潜力的响应式设计解决方案。它只需要最小的下载量而能达到最大的可伸缩性。

<link rel="stylesheet" href="http://weloveiconfonts.com/api/?family=zocial" />

<a href="#" class="zocial-facebook">Facebook</a>
<a href="#" class="zocial-twitter">Twitter</a>
<a href="#" class="zocial-googleplus">Google+</a>
<a href="#" class="zocial-digg">Digg</a>
[class*="zocial-"]:before {
color: black;
display: inline-block;
font-family: 'zocial', sans-serif;
text-shadow: 3px 3px 3px #aaa;
width: 2em;
}

SVG 和数据 URI 内嵌图片


说到文本,如果你真的想要减少网页的文件请求数量,那你可以利用代码实现内嵌图片。有两种方式可以做到,就是 SVG 或者 DataURIs

内嵌 SVG 具有非常好的手机和电脑浏览器支持,并且优化工具可以极大的减少 SVG 的字节。

DataURIs 提供了一种将文件 例如图片 内嵌为一个 base64 编码的字符串,使用格式如下:

<img src="data:image/svg+xml;base64,[data]">

SVG一样 DataURIs也有很好的手机和电脑浏览器支持

但是 DataURIsSVG 还可以内嵌在 CSS 里,手机和电脑都支持。

一些不同的技巧,用来处理网页的图片


  • 利用 外部文件 然后把它们链接到你的 HTML <img src="file.png">
  • 或者可以使用 内嵌图片 将你需要的所有图片数据都放在你的网页中 <img src="data:image/png;base64.....">
  • 可以利用 光栅图片
  • 可以用 矢量图片
  • 将图片打包然后用类似 font awesome图标字体 <i class="fa fa-adjust"></i> 然后利用css技术为它们添加效果

小练习


当你在 开发一个手机应用来展示随时会变化的商品,你需要一张 星星图片 放在右上角,你希望这个图片能够在应用中自由缩放以分别适应手机及电脑客户端的显示,所以,你应该选择 矢量图片 还是 光栅图片? 是 内嵌图标 还是 外部文件链接

答案: 矢量图片 内嵌图标 或者 外部文件链接 都可以。站在 内嵌图标 的角度,星星是一个非常简单的图形,很容易创建出它的 SVG 文件,并且内嵌它们并不会增加太多字节;如果需要重复利用这张图片,链接外部文件也有道理,这意味着可以缓存图片,当用户每查看新一个网页时也不用再次加载它。

开发一个可以自行发布图片日记的手机网站,也就是说图片都是单次利用的。用户会创建一些独有的网页来发布单张图片并佐以说明文字,你应该把它们转化为 矢量图 还是 仅仅保留格式为 .jpg 的图片呢?是 内嵌图片 还是 设置它们的 src 属性来链接外部文件呢?

答案: 首先,用户的图片应该仍然被保留为 jpeg 格式,这些图片本来就是光栅图,所以还是以光栅图的形式保存它们。

考虑到你的用户是手机上访问网站,实际上内嵌图片是个不错的想法,如果你可以做到的话。内嵌图片可以减少浏览器的请求次数,而文件请求是造成手机访问延迟和网页加载不全的重要原因之一。文件请求会增加往返通讯,而往返通讯是手机网页加载缓慢的最重要因素之一。但是内嵌图片会限制你的响应式网站,这个下面会讲到,所以最终,外部文件链接依然可以是一种选择。

开发一个公司网站,公司希望它的 logo 出现在任何一个页面的左上角,很有可能他们还希望一个更大版本的公司logo能出现在搜索引擎的着陆页面,通常来说,用户可以通过手机或者电脑的任何一种来访问,所以你应该使用logo的 矢量图片 还是 光栅图片? 是 内嵌logo图片 还是 设置它的 src 外部文件链接呢?

答案: 第一个问题是 应该使用 矢量图,首先,这个logo 非常简单,因为它是基于文本的,所以将其装换为矢量图不会太困难,其次,你希望它有一大一小两个版本,矢量图可伸缩性很好。所以 logo 的大小版本可以使用同一个源文件。

第二个问题,我觉得应该选择外部文件链接,这样它可以被用于多个页面,浏览器可以将它缓存。

你在创建一个叫做 vicarious concerts 的 移动网页应用,用来比较任意观众为音乐会录制的视频,每个视频的加载都需要几秒钟的时间,你决定显示一个旋转的光碟图标,在视频加载时,出现在视频的位置,你应该用这个光碟图标的 gif动画 还是 svg 动图 呢?是应该 内嵌 这个旋转动画呢?还是 设置它的 src 外部文件链接呢?

答案: 第一个问题是 应该使用 svg 动图;首先,矢量图形更好因为它们可以被无限伸缩而不像 gif 是光栅图形;其次,svg 文件实际上要比 gif 文件小,因为你用的是同一张图片,只是生成了它的旋转动画,而不是播放许多张光碟的图片来表示它在旋转时每个时刻的样子。

第二个问题,选择外部文件链接就很合理,因为多个视频都使用同一个旋转光碟的图标,让浏览器缓存动画再应用到各个页面非常合理。

image 的 srcset 属性


srcset 有两种自定义方式,一种使用 x 来区分设备像素比 (DPR)另一种使用 w 来描述图像的宽度。

对设备像素比的反应:

<img src="image_2x.jpg" srcset="image_2x.jpg 2x, image_1x.jpg 1x" alt="a cool image">

srcset 设置为与逗号分隔的一连串 filename multiplier 对相等,其中每个 multiplier乘数 必须是后跟 x 的整数。

例如,1x 表示 1 倍显示屏,2x 表示像素密度为两倍的显示屏,如 Apple 的 Retina 显示屏。

浏览器会下载与其 DPR 对应的最佳图片。

另请注意,有一个作为备用的 src 属性。

对图片宽度的反应:

<img src="image_200.jpg" srcset="image_200.jpg 200w, image_100.jpg 100w" alt="a cool image">

srcset 设置为与逗号分隔的一连串 filename widthDescriptor 对相等,其中每个 widthDescriptor宽度描述符 都以像素为测量单位, 并且必须是后跟 w 的整数。在这里,widthDescriptor宽度描述符 指定每个图片文件的自然宽度,使浏览器能够根据窗口大小和 DPR 选择要请求的最适当的图片。 (如果有 widthDescriptor宽度描述符,浏览器下载图片才能知道其宽度!)

另请注意,有一个作为备用的 src 属性。

包含大小的图片宽度
如果图片不以全窗口宽度显示会怎样?那么,除了 srcset 外,你还需要其他元素(假设图片将为全窗口宽度)

向包含媒体查询的图片添加一个 sizes 属性和一个 vw 值。srcsetsizes 合起来可让浏览器知道图片的自然宽度以及图片相对于窗口宽度的显示宽度。 知道图片的显示宽度和可用图片文件的宽度后,浏览器将获得下载具有满足其需求的适当分辨率且尽可能小的图片所需的信息。 而且,浏览器在页面加载初期,解析 HTML 时即可做出此选择。

srcset 与 sizes 配合使用的语法
示例:

<img class="w"
src="images/great_pic_800.jpg"
sizes="(max-width: 400px) 100vw, (min-width: 401px) 50vw"
srcset="images/great_pic_400.jpg 400w, images/great_pic_800.jpg 800w"
alt="great picture">

在本示例中,如果浏览器的窗口宽度等于或小于 400 像素,浏览器知道图片将为全窗口宽度;如果窗口宽度大于 400 像素,则为一半窗口宽度。浏览器知道它具有两个图片选项 - 一个具有 400 像素的自然宽度,另一个具有 800 像素。

<img class="w"
src="images/Coffee_1280w.jpg"
srcset="images/Coffee_1280w.jpg 1280w, images/Coffee_640w.jpg 640w"
sizes="(max-width: 960px) 50vw, 100vw"
alt="Coffee by Amy March from Turkey">

在本示例中,浏览器知道它可以选择使用Coffee_1280w.jpg 和Coffee_640w.jpg,宽度分别为1280px和640px。如果页面宽度为960px或更小,浏览器图像将以一半窗口宽度 50vw显示,否则图像将显示为全窗口宽度 100vw。

我没有在 sizes 中包括第二个媒体查询,因为如果没有媒体查询,列出的宽度会被视为默认值。

另外请注意,sizes 中的媒体查询与 CSS 匹配。说明一下,更改 sizes 不会影响 CSS。它只会提醒浏览器注意最终需要在该处显示的图片。

sizes 由以逗号分隔的 mediaQuery width 对组成。sizes 会在加载流程初期告诉浏览器,该图片会在点击 mediaQuery 时以某个 width 显示。

实际上,如果 sizes 缺失,浏览器会将 sizes 默认为 100vw,表示它预计图片将以全窗口宽度显示。

sizes 会为浏览器额外提供一条信息,以确保它根据图片的最终显示宽度下载正确的图片文件。说明一下,它实际上不会调整图片的大小 - 这是 CSS 的工作。

Picture polyfill

响应式图片社区

小结


通过这节,你已经学会图片并不总是必要的,利用 css 和 图标字体来替代传统图片给响应式设计提供了高性能的解决方案。

综合练习

要求:

  • 首先,找到笑脸标志,这是个PNG 图片,把它替换成 Unicode 字符
  • 博客怎能没有社交链接,利用 zocial 在页面底部添加一些社交媒体链接
  • 看到底部那张诡异的装饰图了吗?是个 PNG 图片,它显然非常的不合时宜,所以请将它替换成一个更合理的内容
  • 你可以添加一个响应式 logo,尽情发挥你的灵感
  • 利用 picture 元素提供不同尺寸的图片基于不同的视窗宽度
  • 利用 source 属性设置不同的图片基于设备的像素比
  • 并为所有图片添加合适的 alt 属性

项目链接

项目参考答案

延展

-------------本文结束 感谢您的阅读-------------
0%