结合 HiDPI 监视器了解 srcset 和大小
Understanding srcset and sizes in combination with HiDPI monitors
我进入 CSS 已经有一段时间了,但是图像元素的 srcset
和 sizes
让我很困惑。这是我认为可行的示例。
<img alt="Background image flowers"
srcset="img/flowers-480.jpg 480w,
img/flowers-480@2x.jpg 480w 2x,
img/flowers-768.jpg 768w,
img/flowers-768@2x.jpg 768w 2x,
img/flowers-960.jpg 960w,
img/flowers-960@2x.jpg 960w 2x,
img/flowers-1280.jpg 1280w,
img/flowers-1280@2x.jpg 1280w 2x"
sizes="(max-width: 1279px) 100vw,
(min-width: 1280) 1280px"
src="img/flowers-960.jpg">
我们的想法是让图像占视口的 100%,直到视口达到 1280 像素或更宽,然后图像将固定大小。但是,为了补偿更高 DPI 设备,我认为建议按照建议添加 DPI 描述符(1.5x、2x 等)here and here。
我认为上面的代码会做的是:
- 检查大小,查看图像的预期大小(如果给出了相对单位,例如 % 或 vw,请计算像素宽度)
- 在 srcset 宽度中找到最接近该宽度的图像
- 从这些图像中,过滤掉 DPI 描述符最接近设备 DPI 的图像
但是,当我将其通过验证器时,出现以下错误:
Error: Bad value for attribute srcset on element img: Width for image img/flowers-480@2x.jpg
is identical to width for image
img/flowers-480.jpg
很明显,我完全忽略了 srcset 和 sizes 的工作原理。我做错了什么?
根据 MDN 为 <img srcset="...">
定义:
Each string is composed of:
a URL to an image, optionally, whitespace followed by one of:
- a width descriptor, or a positive integer directly
followed by '
w
'. The width descriptor is divided by the source size
given in the sizes
attribute to calculate the effective pixel density.
- a pixel density descriptor, which is a positive floating point number
directly followed by '
x
'.
您试图同时使用两者,这是非法的。
根据 MDN,“在同一个 srcset 属性中混合宽度描述符和像素密度描述符是不正确的。重复的描述符(例如,同一个 srcset 中的两个源都用'2x'描述)是无效的,也是。
您 2x
列出了 4 次。那是无效的。
这是来自 MDN 的示例:
示例 4:使用 srcset
和 sizes
属性
当使用 'w' 描述符时,支持 srcset
的用户代理会忽略 src
属性。当 (max-width: 600px)
媒体条件匹配时,图像将为 200px 宽,否则将为 50vw 宽(视口宽度的 50%)。
<img src="clock-demo-thumb-200.png"
alt="Clock"
srcset="clock-demo-thumb-200.png 200w,
clock-demo-thumb-400.png 400w"
sizes="(max-width: 600px) 200px, 50vw">
对于图像的 HPDI 设置和响应大小的组合,您实际上应该使用 <picture>
以及一些 <source>
和后备 <img>
元素。
详情为in this article。
, quoted from developers.google.com 中链接的“艺术指导用例”展示了如何将宽度和像素密度结合起来作为加载和显示图像源的标准:
<picture>
<source media="(min-width: 800px)" srcset="head.jpg, head-2x.jpg 2x">
<source media="(min-width: 450px)" srcset="head-small.jpg, head-small-2x.jpg 2x">
<img src="head-fb.jpg" srcset="head-fb-2x.jpg 2x" alt="a head carved out of wood">
</picture>
在至少 800 像素宽的视口中,head.jpg
应显示在单密度显示器上,而 head-2x.jpg
应显示在双倍或更高密度的显示器上。
低于 800 像素但至少 450 像素宽的视口,single-density 显示器应显示 head-small.jpg
,而 head-small-2x.jpg
用于双倍密度或更高密度。
<img>
标签内的回退图像定义有另一个 srcset
,它定义了一个 double-density 版本 (head-fb-2x.jpg
),用于宽度低于 450 像素的视口。
Single-density 不支持源集或图片元素的设备和浏览器将回退显示 head-fb.jpg
。
在更复杂的情况下,我们还可以添加替代图像格式,以利用 webp
压缩,同时为不支持 webp
的浏览器提供 jpg
版本。
<picture>
<source media="(min-width: 800px)" srcset="head.webp, head-2x.webp 2x" with="800" height="941">
<source media="(min-width: 800px)" srcset="head.jpg, head-2x.jpg 2x" with="800" height="941">
<source media="(min-width: 450px)" srcset="head-small.webp, head-small-2x.webp 2x" width="800" height="941">
<source media="(min-width: 450px)" srcset="head-small.jpg, head-small-2x.jpg 2x" width="800" height="941">
<img src="head-fb.jpg" srcset="head-fb-2x.jpg 2x" width="400" height="471" alt="a head carved out of wood">
</picture>
这里是一个codepen的复杂例子。
到 2022 年,我认为假设高 DPI 屏幕并利用 srcset
:
的断点想法会更容易
<img alt="Background image flowers"
srcset="img/flowers-480.jpg 480w,
img/flowers-768.jpg 768w,
img/flowers-960.jpg 960w,
img/flowers-1280.jpg 1280w"
sizes="(max-width: 1279px) 100vw,
(min-width: 1280) 1280px"
src="img/flowers-960.jpg">
我进入 CSS 已经有一段时间了,但是图像元素的 srcset
和 sizes
让我很困惑。这是我认为可行的示例。
<img alt="Background image flowers"
srcset="img/flowers-480.jpg 480w,
img/flowers-480@2x.jpg 480w 2x,
img/flowers-768.jpg 768w,
img/flowers-768@2x.jpg 768w 2x,
img/flowers-960.jpg 960w,
img/flowers-960@2x.jpg 960w 2x,
img/flowers-1280.jpg 1280w,
img/flowers-1280@2x.jpg 1280w 2x"
sizes="(max-width: 1279px) 100vw,
(min-width: 1280) 1280px"
src="img/flowers-960.jpg">
我们的想法是让图像占视口的 100%,直到视口达到 1280 像素或更宽,然后图像将固定大小。但是,为了补偿更高 DPI 设备,我认为建议按照建议添加 DPI 描述符(1.5x、2x 等)here and here。
我认为上面的代码会做的是:
- 检查大小,查看图像的预期大小(如果给出了相对单位,例如 % 或 vw,请计算像素宽度)
- 在 srcset 宽度中找到最接近该宽度的图像
- 从这些图像中,过滤掉 DPI 描述符最接近设备 DPI 的图像
但是,当我将其通过验证器时,出现以下错误:
Error: Bad value for attribute srcset on element img: Width for image
img/flowers-480@2x.jpg
is identical to width for imageimg/flowers-480.jpg
很明显,我完全忽略了 srcset 和 sizes 的工作原理。我做错了什么?
根据 MDN 为 <img srcset="...">
定义:
Each string is composed of:
a URL to an image, optionally, whitespace followed by one of:
- a width descriptor, or a positive integer directly followed by '
w
'. The width descriptor is divided by the source size given in thesizes
attribute to calculate the effective pixel density.- a pixel density descriptor, which is a positive floating point number directly followed by '
x
'.
您试图同时使用两者,这是非法的。
根据 MDN,“在同一个 srcset 属性中混合宽度描述符和像素密度描述符是不正确的。重复的描述符(例如,同一个 srcset 中的两个源都用'2x'描述)是无效的,也是。
您 2x
列出了 4 次。那是无效的。
这是来自 MDN 的示例:
示例 4:使用 srcset
和 sizes
属性
当使用 'w' 描述符时,支持 srcset
的用户代理会忽略 src
属性。当 (max-width: 600px)
媒体条件匹配时,图像将为 200px 宽,否则将为 50vw 宽(视口宽度的 50%)。
<img src="clock-demo-thumb-200.png"
alt="Clock"
srcset="clock-demo-thumb-200.png 200w,
clock-demo-thumb-400.png 400w"
sizes="(max-width: 600px) 200px, 50vw">
对于图像的 HPDI 设置和响应大小的组合,您实际上应该使用 <picture>
以及一些 <source>
和后备 <img>
元素。
详情为in this article。
<picture>
<source media="(min-width: 800px)" srcset="head.jpg, head-2x.jpg 2x">
<source media="(min-width: 450px)" srcset="head-small.jpg, head-small-2x.jpg 2x">
<img src="head-fb.jpg" srcset="head-fb-2x.jpg 2x" alt="a head carved out of wood">
</picture>
在至少 800 像素宽的视口中,head.jpg
应显示在单密度显示器上,而 head-2x.jpg
应显示在双倍或更高密度的显示器上。
低于 800 像素但至少 450 像素宽的视口,single-density 显示器应显示 head-small.jpg
,而 head-small-2x.jpg
用于双倍密度或更高密度。
<img>
标签内的回退图像定义有另一个 srcset
,它定义了一个 double-density 版本 (head-fb-2x.jpg
),用于宽度低于 450 像素的视口。
Single-density 不支持源集或图片元素的设备和浏览器将回退显示 head-fb.jpg
。
在更复杂的情况下,我们还可以添加替代图像格式,以利用 webp
压缩,同时为不支持 webp
的浏览器提供 jpg
版本。
<picture>
<source media="(min-width: 800px)" srcset="head.webp, head-2x.webp 2x" with="800" height="941">
<source media="(min-width: 800px)" srcset="head.jpg, head-2x.jpg 2x" with="800" height="941">
<source media="(min-width: 450px)" srcset="head-small.webp, head-small-2x.webp 2x" width="800" height="941">
<source media="(min-width: 450px)" srcset="head-small.jpg, head-small-2x.jpg 2x" width="800" height="941">
<img src="head-fb.jpg" srcset="head-fb-2x.jpg 2x" width="400" height="471" alt="a head carved out of wood">
</picture>
这里是一个codepen的复杂例子。
到 2022 年,我认为假设高 DPI 屏幕并利用 srcset
:
<img alt="Background image flowers"
srcset="img/flowers-480.jpg 480w,
img/flowers-768.jpg 768w,
img/flowers-960.jpg 960w,
img/flowers-1280.jpg 1280w"
sizes="(max-width: 1279px) 100vw,
(min-width: 1280) 1280px"
src="img/flowers-960.jpg">