惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

L
LangChain Blog
月光博客
月光博客
S
SegmentFault 最新的问题
博客园 - 三生石上(FineUI控件)
Last Week in AI
Last Week in AI
J
Java Code Geeks
酷 壳 – CoolShell
酷 壳 – CoolShell
TaoSecurity Blog
TaoSecurity Blog
V
Visual Studio Blog
博客园 - 叶小钗
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
T
Threat Research - Cisco Blogs
罗磊的独立博客
雷峰网
雷峰网
T
Tor Project blog
L
LINUX DO - 最新话题
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
博客园 - 司徒正美
Apple Machine Learning Research
Apple Machine Learning Research
Scott Helme
Scott Helme
Spread Privacy
Spread Privacy
C
CERT Recently Published Vulnerability Notes
腾讯CDC
Cloudbric
Cloudbric
WordPress大学
WordPress大学
Security Archives - TechRepublic
Security Archives - TechRepublic
V
V2EX
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
N
News and Events Feed by Topic
T
Troy Hunt's Blog
T
Threatpost
C
Check Point Blog
Vercel News
Vercel News
I
Intezer
Engineering at Meta
Engineering at Meta
C
Cybersecurity and Infrastructure Security Agency CISA
D
DataBreaches.Net
SecWiki News
SecWiki News
Help Net Security
Help Net Security
Microsoft Azure Blog
Microsoft Azure Blog
Google DeepMind News
Google DeepMind News
S
Secure Thoughts
T
The Blog of Author Tim Ferriss
The GitHub Blog
The GitHub Blog
Hacker News: Ask HN
Hacker News: Ask HN
AI
AI
N
News and Events Feed by Topic
阮一峰的网络日志
阮一峰的网络日志
B
Blog RSS Feed
Attack and Defense Labs
Attack and Defense Labs

郭泽宇的博客 (@ZE3kr)

Hertz 租车被讨债总结,我起诉讨债公司的经历 | ZE3kr 在 iPad 上运行 macOS? (with Jump Desktop) Vision Pro 首发体验 | ZE3kr 低价冷数据存储方案 - Lightsail + S3 + Nextcloud 实现 $1/TB/月 谈一谈阿里云香港的宕机 | ZE3kr 云服务推荐及选择指南 | ZE3kr 从零开始建立自己的域名和企业邮箱 | ZE3kr 本站改版后的架构与优化——Hexo,分区解析,CDN,图像压缩等 | ZE3kr 毫米波 5G 有多快? 2000Mbps! 快来看看你的 iPhone 是否支持毫米波 Mac mini 有什么用?组建家庭服务器! | ZE3kr Magic Keyboard (妙控键盘) for iPad Pro 使用体验 自建 PowerDNS 进阶:分区解析,dnsdist,Lua 记录 | ZE3kr SSD U盘、Windows To Go 与 Mac WordPress 5.0 更新现已发布,全新编辑器,全新主题 | ZE3kr Azure DNS、NS1、Constellix,三家海外 GeoDNS 服务商对比 | ZE3kr Mac 上一些精致实用的软件推荐 | ZE3kr 谈谈数据备份 | ZE3kr DNSSEC 简介,签名的工作原理 | ZE3kr Cloudflare Argo 与 Railgun 对比测试,CDN 加速的黑科技 几个免费的服务器监控服务推荐 | ZE3kr 国内外几家全站 CDN 对比 | ZE3kr 2017 年,再看 SSL 和 HTTPS 关于建站和服务选购的一些建议 | ZE3kr DNS 域名解析系统详解——基础篇 | ZE3kr 修复 WordPress 2017 主题中奇怪字形的 Bug 使用 AMP 构建超快的移动页面 | ZE3kr 利用 GCE 建立一个 Anycast 网络,超快的香港节点,Google Cloud CDN Cloudflare 的全新功能体验——Load Balancing、Rate Limiting | ZE3kr Google Compute Engine 新手教程及使用体验 | ZE3kr 用回 WordPress 自带评论系统 | ZE3kr 使用免费 Let's Encrypt 实现 ECDSA/RSA 双证书 如何配置以实现纯 IPv6-Only 网络访问 | ZE3kr 自建 PowerDNS 智能解析服务器 | ZE3kr 在自己服务器上安装 GitLab,代替 GitHub! | ZE3kr 几个 WordPress 的加速建议 | ZE3kr CloudXNS、Route 53、阿里云解析等 DNS 服务的全面对比 | ZE3kr 从沙州中学到家 | ZE3kr 从家到沙州中学 | ZE3kr 谈谈视频在互联网上的流播 | ZE3kr 佳能发布新 APS-C 机型 EOS 80D,强悍视频录制、全新的对焦系统和 CMOS WordPress 上的几个推荐安装的插件 | ZE3kr Matomo 与 WordPress 配合使用,建立强大统计系统 | ZE3kr TL-PA500 电力猫,部署无线局域网集群 | ZE3kr 为何要使用一个 CDN 服务? | ZE3kr 静态网页的优与劣 | ZE3kr 全面 HTTPS 时代即将到来 | ZE3kr Withings Activité Pop 智能手表推荐,睡眠跟踪、运动记录、智能闹钟 | ZE3kr DELL P2415Q 4K 显示器推荐 | ZE3kr 好搜所做的恶心事 | ZE3kr Eyefi Mobi 立刻让你的相机支持 Wi-Fi | ZE3kr 移动优先 – 速度 | ZE3kr MacID 让 iPhone 指纹解锁苹果电脑 | ZE3kr ProCamera – iPhone 照相软件推荐 | ZE3kr 移动优先 – 起源 | ZE3kr
使用 srcset + sizes 属性与 w 标识符解决一切响应式图片问题
2015-08-17 · via 郭泽宇的博客 (@ZE3kr)

使用 srcset 属性可以解决一切响应式图片问题,但这里分为两种情况,确定和不确定宽度的照片。相比之下,不确定宽度的照片更复杂些。

确定宽度的照片

此处指的确定宽度照片,是指样式属性宽度设置为一个确定了多少 px 的照片。 随着越来越多的高设备像素比(指 device pixel ratio,下同)显示器出现,网站需要更高像素的照片来适配这些显示器。 比如有一张照片显示宽度为 200px,它在@1x(即设备像素比为 1 的显示器,下同) 的显示器上,是占了 200 个物理像素(即实际所占的像素,下同);它在 @2x 的显示器上,实际上是占了 400 个物理像素;在 @3x 的显示器上,实际上是占了 600 个物理像素;同样的,在 @4x 的显示器上就是占了 800 个物理像素。 如果这个照片只提供 200 像素的版本,那么在 @2x~@4x 的显示器上看起来就很模糊。如果只提供 800 像素的版本,那么在 @1x~@3x 的设备上会加载不必要的内容,也就意味着更长的不必要时间(尤其是在手机上)。 此时,就需要使用响应式图片这个方法,最简单高效的方式是使用 srcset 来解决。比如现在提供了 4 个宽度分别为 200、400、600、800 像素的照片,通过 srcset 属性,能够实现在 @1x~@4x 设备像素比的显示器上分别显示这 4 张照片,这样在每个显示器上都能显示最适合它的照片。这四张图片的文件名分别为 200px.png, 400px.png, 600px.png, 800px.png。 总结一下,就是确定宽度的照片所占物理的像素只与设备像素比有关,所以只需要 srcset 属性的 x 标识符。

1
<img src="200px.png" srcset="400px.png 2x, 600px.png 3x, 800px.png 4x">

这样加上 srcset 属性,浏览器就会根据自己的设备像素比来加载不同的照片,不支持 srcset 属性的浏览器就默认加载 200px.png 这张照片。这个方法是向下兼容的。

不确定宽度的照片

此处指的不确定宽度的照片,是指样式属性宽度设置为一个确定了多少百分比的照片。 如果是不确定宽度的照片的话(或者是手机上不确定图片宽度,电脑上确定宽度等),也可以通过 srcset 解决。由于像素是不能确定的,所以很难达到照片本身和照片所占物理像素是一样的,因为用户的窗口大小是不确定的。 如果只准备 5 张照片,宽度分别是 400~3200 像素,文件名是400px.png, 800px.png, 1600px, 2400px, 3200px。通常,如果没有对应图像所占的物理像素的照片的话,则会加载比所占的物理像素稍大一些的图片。例如照片占屏幕的 500 个物理像素,那么就应该选择加载 800px.png。这样加载稍大的照片仍然可以达到最佳的显示效果,同时最大限度的节省网络资源。 总结一下,就是不确定宽度的照片所占物理的像素与设备像素比和所占宽度有关,然而使用了 srcset 属性的 w 标识符后,你只需要指定宽度,浏览器会自动根据设备像素比来选择最优图片。 如果这个图片占整个窗口的 100% 大小(即 100vw 宽,下同),那么只需要这样设置 srcset 就能达到效果。 抛开设备像素比的概念吧,这个全新的 srcset 属性的 w 标识符能够让浏览器自己适应所要加载的照片。

1
<img src="800px.png" srcset="400px.png 400w, 800px.png 800w, 1600px.png 1600w, 2400px.png 2400w, 3200px.png 3200w" alt="" />

不过此时还有一个小问题,浏览器比较笨,它会认为图片宽度始终是整个窗口的 100% 宽,如果图片不是占整个窗口的 100%,两边留有边框怎么办呢?此时就需要使用 size 属性。 sizes 属性里制定图片的宽度,不能使用百分比单位,但可以使用 vw、px 等单位(100vw 就是整个窗口的宽度),也可以使用 calc 运算,同时支持媒体查询。要保证使用 sizes 里计算出来的宽度始终是图片所占屏幕宽度,剩下的事情都只需要浏览器完成了。 以下几种典型案例示范:

两边边框为百分比

如果图片两侧边框(指图片边缘到窗口边缘长度)始终是占屏幕的一定的百分比时,那么图片总会有一个相对于整个窗口的百分比。比如图片两侧边框始终是整个窗口的 10%,那么 size 属性就可以如下设置:

1
sizes="80vw"

如果图片已经在一个宽度是整个窗口的 70% 的元素下,而且元素内图片两侧还留有 10% 的边框,那么 size 属性就可以如下设置:

1
sizes="50vw"

两边边框为确定的像素

比如图片两侧边框始终是 10px,那么 size 属性就可以如下设置:

1
sizes="calc( 100vw - 10px )"

如果图片已经在一个宽度是整个窗口的 70% 的元素下,而且元素内图片两侧边框始终是 10p,那么 size 属性就可以如下设置:

1
sizes="calc( 70vw - 10px )"

图片有最大尺寸

比如图片两侧边框始终是 10px,但是图片最大只能是 1000px,那么 size 属性就可以如下设置:

1
sizes="(min-width: 1020px) 1000px, calc( 100vw - 10px )"

其中 (min-width: 1020px) 1000px 代表当屏幕像素宽度大于 1020px 时,图片宽度为 1000px。

实际效果

此处以我的网站为例,我的网站图片边框适中是 1.875rem,这个图片本身就是在一个元素下,这个元素默认宽度是整个窗口的 100%,但在屏幕宽度大于 40.063rem 的情况下,这个元素占整个窗口的 50%,并且这个元素有最大尺寸 500px,现在把 size 属性和用 w 标识符的 srcset 属性放在一起,就完美解决了。

1
<img src="800px.png" sizes="(min-width: 1000px) calc( 500px - 1.875rem ), (min-width: 40.063rem) calc( 50vw - 1.875rem ), calc( 100vw - 1.875rem )" srcset="400px.png 400w, 800px.png 800w, 1600px.png 1600w, 2400px.png 2400w, 3200px.png 3200w" alt="" />

然后你就可以在浏览器中测试了,达到了适配所有屏幕尺寸,所有设备像素比的效果。

关于兼容性

通常情况下,srcset 属性的 x 标识符支持的比 w 标识符更好,因为 w 标识符是一个新的属性。不过好消息是 Chrome 38+、Firefox 38+、Safari 9+、Opera 30+、Android 5.0+、iOS 9+(没错,IE/Edge、Windows Phone 截止到写文章之日都不支持) 都纷纷支持了 w 标识符,所以我认为现在很适合换用 srcset 属性的 w 标识符来做响应式图片了。而且这个方法是完美向下兼容的,即使不支持也没关系。 你也可以在 CanIUse.com 上查询关于 secset 属性的完整的兼容性列表