(八):CSS图片
最后更新于:2022-04-01 03:43:03
> 译文出处:http://www.w3cplus.com/responsive/responsive-images-101-part-8-css-images.html
> 英文原文:http://blog.cloudfour.com/responsive-images-101-part-8-css-images/
大多数时候谈到响应式图片,人们指的是内联图片,而不是CSS图片。
这是因为在`<picture>`和`srcset`之前内联响应式图片还没有好的解决方案。但遇到CSS图片时,我们可以使用媒体查询,那还有什么可担心呢?
现在是时候回顾响应式CSS图片并基于我们已经学过的内联图片寻找解决方案。
## 分辨率切换的解决方案`image-set()`
与我们正在研究的内联图片一样,首先需要考虑的问题是当前的情况是[分辨率切换](http://www.w3cplus.com/responsive/responsive-images-101-definitions.html)还是[艺术指导](http://www.w3cplus.com/responsive/responsive-images-101-definitions.html)。
对于分辨率切换来说,我们需要尽可能给浏览器提供选择并让浏览器选择可能最佳的图片。浏览器基于用户配置,网站环境等因素能够知道哪张图片可能最适合。
要给浏览器提供选项,我们应该使用[`image-set()`语法](http://www.w3cplus.com/css/safari-6-and-chrome-21-add-image-set-to-support-retina-images.html)。
![image set](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-10-08_5615d1053e0b8.png "image set")
你也许会注意到`image-set()`和`srcset`之间的一些联系。事实上,`srcset`是仿照`image-set()`的。
~~~
background-image: image-set( "foo.png" 1x, "foo-2x.png" 2x);
~~~
与`srcset`类似,`image-set`的值包含逗号分隔的图片`URL`列表以及屏幕分辨率描述符。如果没有提供屏幕分辨率描述符,默认为`1`倍。
然而`image-set()`仍不支持宽度描述符。计划是改善`image-set()`来提供与`srcset`等价的特性。
虽然你看到大部分`image-set()`例子都是用在`background-image`上,它其实可以用在任何可以使用图片的CSS属性上。
## image-set():被遗忘的响应式图片标准
`image-set()`是第一代响应式图片规范语法,正如本文所提到的那样,它是`srcset`的基础。
然而,因为普遍使用媒体查询解决CSS响应式图片问题,`image-set()`几乎被所有人忽视了。响应式图片研究小组没有花很多时间来讨论它。浏览器没有优先支持它。
当`<picture>`和`srcset`的标准几乎完成后,我们环顾四周意识到需要重新协商`image-set()`,于是我们已经开始增强`image-set()`的功能并把它嵌入`srcset`。
众所周知,虽然`image-set()`是第一个响应式图片标准,但是它依然缺乏浏览器支持。在Chrome,Opera和Safari中[添加webkit前缀可用](http://caniuse.com/#search=image-set)。Firefox和Microsoft都还没有支持。
那么为什么我们要在[响应式图片101系列](http://www.w3cplus.com/blog/tags/509.html)里提到呢?
因为`image-set()`是分辨率切换的正确解决方案。当`image-set()`被广泛支持时,面对分辨率切换的情况我们应当使用它[而不是带媒体属性的`<picture>`元素](http://blog.cloudfour.com/dont-use-picture-most-of-the-time/),原因与使用带媒体属性的`<picture>`相同。
直到`image-set()`被广泛支持前,你还是会使用CSS艺术指导方案来解决分辨率切换。
## 艺术指导
艺术指导的CSS解决方案是什么呢?媒体查询。
这很简单,事实上我假定你已经对媒体查询有所了解因此没有提供语法样例。
但是请听我说,请确保图片的媒体查询没有重叠否则会导致重复下载图片。如果有任何疑问,查看Tim Kadlec的[媒体查询和资源下载结果](http://timkadlec.com/2012/04/media-query-asset-downloading-results/)。
## 分辨率媒体查询
如果你想在高分辨率屏幕下支持艺术指导,那肯定想用分辨率媒体查询。
![image set](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-10-08_5615d1061e7ed.png "image set")
分辨率媒体查询让你可以针对满足定义分辨率的设备屏幕添加特定CSS规则。
~~~
@media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) {/* High density stuff here */}
~~~
(非常感谢CSS Tricks提供[语法样例](https://css-tricks.com/snippets/css/retina-display-media-query/)。)
上述语法中你首先会注意到的是我们加入了包含`-webkit`前缀的媒体查询。这是为了支持老`device-pixel-ratio`语法的机器。只有一台机器支持这个带`-webkit`前缀的语法所以只列出了一台。
更近一步的语法是分辨率媒体查询。在我们的例子中,我们用了最小分辨率,但是正如你猜到的那样,当然有最大分辨率这个功能可以使用。
分辨率媒体查询可以检查以下三种情况:
* **`dip`**:点每英尺
* **`dpcm`**:点每厘米
* **`dppx`**:点每像素
前两个单位很直观,对于`dppx`我有写疑惑。Mozilla网络开发文档这样[定义`dppx`](https://developer.mozilla.org/en-US/docs/Web/CSS/resolution):
> 这个单位代表每像素单位上点的数目。因为CSS中`in`与`px`的比例固定为`1:96`,`1dppx`等于`96dpi`,这与CSS中由图片分辨率定义的默认图片分辨率显示有关。
有一点疑惑?刚开始看到我也是这样。
我是这样想的,`1x`,`2x`,`3x`等都基于不明确的定义。一些设备上`1`倍的值与其它设备不同因为一些设备的分辨率是`72dpi`或`96dpi`以及其它。
然而从CSS的角度看,这些差异无关紧要。CSS工作组决定了CSS中`in`与`px`的比例固定为`1:96`。
因此,虽然`72dpi`和`96dpi`的博弈导致`1`倍的定义不明确,`1ppx`是大家都认同的“`1`倍”。
你也许会问,`1`倍为什么对于`srcset`和`image-set`那么重要,对于最小分辨率来说,还有必要使用`dppx`吗?
我不知道。我只知道你可以把`1dppx`当做`1`倍,`2dppx`当做`2`倍,以此类推。在这一点上,我刚刚才接受了这个差异并决定继续向前看。我推荐你也这么做。;-)
## 来到最难的部分
信不信由你,响应式图片的语法其实是简单的部分。在下一节里,我们将讨论选择图片断点的巨大挑战。