响应式图片

Web 上的文本会在屏幕边缘自动换行,以避免溢出。另一方面,图片具有固有的尺寸。如果图片比屏幕宽,则图片会溢出,用户必须水平滚动才能看到图片的全部内容。

幸运的是,CSS 为您提供了阻止这种情况发生的工具。

约束您的图片

在样式表中,您可以使用 max-inline-size 声明图片的渲染尺寸永远不能超过其包含元素。

浏览器支持

  • Chrome: 57.
  • Edge: 79.
  • Firefox: 41.
  • Safari: 12.1.

来源

img {
  max-inline-size: 100%;
  block-size: auto;
}

您也可以将相同的规则应用于其他类型的嵌入式内容,例如视频和 iframe。

img,
video,
iframe {
  max-inline-size: 100%;
  block-size: auto;
}

有了此规则,浏览器会自动缩小图片以适应屏幕。

Two screenshots; the first shows an image expanding past the browser width; the second shows the same image constrained within the browser viewport.
约束您的图片可让用户在无需滚动的情况下看到图片的全部内容。

添加 block-size 值为 auto 意味着浏览器在调整图片大小时会保留图片的纵横比。

有时,图片的尺寸由内容管理系统 (CMS) 或其他内容交付系统设置。如果您的设计要求与 CMS 的默认纵横比不同,则可以使用 aspect-ratio 属性来保留您网站的设计

img {
  max-inline-size: 100%;
  block-size: auto;
  aspect-ratio: 2/1;
}

不幸的是,这通常意味着浏览器必须挤压或拉伸图片才能使其适应预期的空间。

Profile of a happy-looking handsome dog with a ball in its mouth, but the image is squashed.
更改图片的纵横比会使其看起来被挤压或拉伸。

要防止挤压和拉伸,请使用 object-fit 属性。

浏览器支持

  • Chrome: 32.
  • Edge: 79.
  • Firefox: 36.
  • Safari: 10.

来源

object-fit 值为 contain 告诉浏览器保留图片的纵横比,并在需要时在图片周围留出空白空间。

img {
  max-inline-size: 100%;
  block-size: auto;
  aspect-ratio: 2/1;
  object-fit: contain;
}

object-fit 值为 cover 告诉浏览器保留图片的纵横比,并在需要时裁剪图片。

img {
  max-inline-size: 100%;
  block-size: auto;
  aspect-ratio: 2/1;
  object-fit: cover;
}
Profile of a happy-looking handsome dog with a ball in its mouth; there is extra space on either side of the image. Profile of a happy-looking handsome dog with a ball in its mouth; the image has been cropped at the top and bottom.
应用了两个不同的 `object-fit` 值的同一张图片。第一个的 `object-fit` 值为 `contain`。第二个的 `object-fit` 值为 `cover`。

您可以使用 object-position 属性更改图片裁剪的位置。这会调整裁剪的焦点,因此您可以确保图片的最重要部分仍然可见。

浏览器支持

  • Chrome: 32.
  • Edge: 79.
  • Firefox: 36.
  • Safari: 10.

来源

img {
  max-inline-size: 100%;
  block-size: auto;
  aspect-ratio: 2/1;
  object-fit: cover;
  object-position: top center;
}
Profile of a happy-looking handsome dog with a ball in its mouth; the image has only been cropped at the bottom.
您可以设置 object-position 以仅裁剪图片的一侧。

交付您的图片

这些 CSS 规则告诉浏览器您希望如何渲染图片。您还可以在 HTML 中提供有关浏览器应如何处理这些图片的提示。

尺寸提示

如果您知道图片的尺寸,请始终包含 widthheight 属性。即使由于您的 max-inline-size 规则,图片以不同的尺寸渲染,浏览器仍然知道宽度与高度的比率,并且可以留出适当的空间。这可以防止您的其他内容在图片加载时跳动。

<img
 src="image.png"
 alt="A description of the image."
 width="300"
 height="200"
>
第一个视频显示了一个没有定义图片尺寸的布局。请注意文本在图片加载时如何跳动。在第二个视频中,已提供图片尺寸,因此浏览器为图片留出空间,并且文本在图片加载时不会跳动。

加载提示

使用 loading 属性告诉浏览器是否延迟加载图片,直到图片位于视口中或附近。对于首屏下方的图片,请使用值 lazy。浏览器不会加载延迟加载的图片,直到用户向下滚动足够远以使图片即将进入视图。如果用户从不滚动,则图片永远不会加载。

<img
 src="image.png"
 alt="A description of the image."
 width="300"
 height="200"
 loading="lazy"
>
延迟加载的图片会等待加载,直到用户即将滚动到它们为止。

对于首屏上方的英雄图片,请勿使用 loading。如果您的网站自动应用 loading="lazy" 属性,您通常可以将 loading 设置为默认值 eager 以防止图片被延迟加载

<img
 src="hero.jpg"
 alt="A description of the image."
 width="1200"
 height="800"
 loading="eager"
>

提取优先级

对于重要图片(例如 LCP 图片),您可以使用 提取优先级 并将 fetchpriority 属性设置为 high 来进一步优先加载

<img
 src="hero.jpg"
 alt="A description of the image."
 width="1200"
 height="800"
 loading="eager"
 fetchpriority="high"
>

这告诉浏览器立即以高优先级提取图片,而不是等到浏览器完成其布局并正常提取图片之后。

但是,当您要求浏览器优先下载一个资源(例如图片)时,浏览器必须降低另一个资源(例如脚本或字体文件)的优先级。仅当图片确实至关重要时,才在图片上设置 fetchpriority="high"

预加载提示

最好尽可能避免预加载,方法是将所有图片都包含在初始 HTML 文件中。但是,某些图片可能不可用,例如 JavaScript 添加的图片或 CSS 背景图片

您可以使用预加载来使浏览器提前提取这些重要图片。对于真正重要的图片,您可以将此预加载与 fetchpriority 属性结合使用

<link rel="preload" href="hero.jpg" as="image" fetchpriority="high">

同样,请谨慎使用这些属性,以避免过于频繁地覆盖浏览器的优先级启发式算法。过度使用它们可能会导致性能下降。

某些浏览器支持基于 srcset预加载响应式图片,使用 imagesrcsetimagesizes 属性。例如

<link rel="preload" imagesrcset="hero_sm.jpg 1x hero_med.jpg 2x hero_lg.jpg 3x" as="image" fetchpriority="high">

通过排除 href 回退,您可以确保不支持 srcset 的浏览器仍然预加载正确的图片。

您无法根据浏览器对某些格式的支持来预加载不同格式的图片。尝试这样做可能会导致额外的下载,从而浪费用户的数据。

图片解码

还有一个 decoding 属性,您可以将其添加到 img 元素。您可以告诉浏览器可以异步解码图片,以便它可以优先处理其他内容。

<img
 src="image.png"
 alt="A description of the image."
 width="300"
 height="200"
 loading="lazy"
 decoding="async"
>

如果图片本身是要优先考虑的最重要的内容,则可以使用 sync 值。

<img
 src="hero.jpg"
 alt="A description of the image."
 width="1200"
 height="800"
 loading="eager"
 decoding="sync"
>

decoding 属性不会更改图片解码的速度。它仅影响浏览器是否等待此图片解码完成才渲染其他内容。

在大多数情况下,这没有太大影响,但有时它可以让浏览器更快地显示您的图片或其他内容。例如,对于包含大量需要渲染的元素以及需要很长时间才能解码的大图片的文档,在重要图片上设置 sync 会告诉浏览器等待图片并同时渲染两者。或者,您可以设置 async 以让浏览器更快地显示内容,而无需等待图片解码。

但是,更好的选择通常是尝试避免过大的 DOM 大小并使用响应式图片来减少解码时间,而不是使用 decoding

带有 srcset 的响应式图片

由于 max-inline-size: 100% 声明,您的图片无法超出其容器。但是,如果用户拥有小屏幕和低带宽网络,则让他们下载与拥有较大屏幕的用户相同尺寸的图片会浪费数据。

要解决此问题,请添加同一图片的不同尺寸的多个版本,并使用 srcset 属性告诉浏览器这些尺寸存在以及何时使用它们。

宽度描述符

您可以使用逗号分隔的值列表定义 srcset。每个值都是图片的 URL,后跟一个空格,然后是一些关于图片的元数据,称为描述符

在此示例中,元数据使用 w 单位描述每个图片的宽度。一个 w 是一个像素的宽度。

<img
 src="small-image.png"
 alt="A description of the image."
 width="300"
 height="200"
 loading="lazy"
 decoding="async"
 srcset="small-image.png 300w,
  medium-image.png 600w,
  large-image.png 1200w"
>

srcset 属性补充了 src 属性,而不是替换它。您仍然需要有一个有效的 src 属性,但浏览器可以用 srcset 中列出的选项之一替换其值。为了节省带宽,浏览器仅在需要时才下载较大的图片。

尺寸

如果您使用宽度描述符,则还必须使用 sizes 属性为浏览器提供更多信息。这告诉浏览器您希望图片在不同条件下显示的尺寸。这些条件在媒体查询中指定。

sizes 属性采用逗号分隔的媒体查询和图片宽度列表。

<img
 src="small-image.png"
 alt="A description of the image."
 width="300"
 height="200"
 loading="lazy"
 decoding="async"
 srcset="small-image.png 300w,
  medium-image.png 600w,
  large-image.png 1200w"
 sizes="(min-width: 66em) 33vw,
  (min-width: 44em) 50vw,
  100vw"
>

在此示例中,您告诉浏览器,在宽度超过 66em 的视口中,它显示的图片宽度不应超过屏幕的三分之一(例如,在三列布局中)。

对于宽度介于 44em66em 之间的视口,以屏幕宽度的一半显示图片(如在两列布局中)。

对于任何比 44em 更窄的宽度,以屏幕的完整宽度显示图片。

这意味着最大的图片不一定用于最宽的屏幕。可以显示多列布局的宽浏览器窗口使用适合一列的图片,该图片可能小于用于较窄屏幕上的单列布局的图片。

使用尺寸描述符来更改页面在不同屏幕尺寸上的布局方式。

像素密度描述符

您还可以使用描述符来提供图片的替代版本,以在高密度显示器上显示,从而使图片在高分辨率下看起来仍然清晰。

Two versions of the same image of a happy-looking handsome dog with a ball in its mouth, one image looking crisp and the other looking fuzzy.
像素密度较低的图片可能看起来模糊。

使用密度描述符来描述图片相对于 src 属性中图片的像素密度。密度描述符是一个数字,后跟字母 x,例如 1x2x

<img
 src="small-image.png"
 alt="A description of the image."
 width="300"
 height="200"
 loading="lazy"
 decoding="async"
 srcset="small-image.png 1x,
  medium-image.png 2x,
  large-image.png 3x"
>

如果 small-image.png 的尺寸为 300 x 200 像素,而 medium-image.png 的尺寸为 600 x 400 像素,则 medium-image.png 可以在 srcset 列表中在其后加上 2x

您不必使用整数。如果图片的另一个版本尺寸为 450 x 300 像素,则可以使用 1.5x 来描述它。

演示图片

HTML 中的图片是内容。这就是为什么您包含 alt 属性,其中包含屏幕阅读器和搜索引擎的图片描述。

如果您嵌入的图片是装饰性的,没有任何有意义的内容,则可以使用空的 alt 属性。

<img
 src="flourish.png"
 alt=""
 width="400"
 height="50"
>

您必须始终包含 alt 属性,即使它是空的。空的 alt 属性告诉屏幕阅读器该图片是演示性的。缺少 alt 属性不会提供该信息。

理想情况下,演示性或装饰性图片应使用 CSS 而不是 HTML 包含。HTML 用于结构。CSS 用于演示。

背景图片

在 CSS 中使用 background-image 属性加载演示图片。

element {
  background-image: url(flourish.png);
}

您可以使用 image-set 函数为 background-image 指定多个图片候选项。

CSS 中的 image-set 函数的工作方式与 HTML 中的 srcset 属性非常相似。为每个图片提供一个带有像素密度描述符的图片列表。

element {
  background-image: image-set(
    small-image.png 1x,
    medium-image.png 2x,
    large-image.png 3x
  );
}

浏览器会选择最适合设备像素密度的图片。

向您的网站添加图片时,需要考虑许多因素,包括

  • 为每张图片预留合适的空间。
  • 弄清楚您需要多少尺寸。
  • 确定图片是内容还是装饰性的。

值得花时间来正确处理您的图片。糟糕的图片策略可能会惹恼和挫败您的用户。良好的图片策略使您的网站感觉流畅清晰,无论用户的设备或网络连接如何。

您的工具包中还有一个 HTML 元素,可让您更好地控制图片:picture 元素

检查您的理解情况

测试您对图片的知识。

必须为图片添加样式才能使其适合视口。

正确
没有包含的图片将与其自然尺寸一样大。
错误
样式是必需的。

当图片的height和width被强制设置为不自然的纵横比时,哪些样式可以帮助调整图片如何适应这些比例?

object-fit
使用 containcover 等关键字指定图片如何适应。
image-fit
此属性不存在,是我编造的。
fit-image
此属性不存在,是我编造的。
aspect-ratio
这可能会导致或解决不自然的图片比例。

在图片上放置 heightwidth 会阻止 CSS 以不同方式设置其样式。

正确
将它们更多地视为提示而不是规则。
错误
即使 height 和 width 是标记内联的,CSS 也具有大量用于调整图片尺寸的动态选项。

srcset 属性不会_______ src 属性,而是_______ 它。

补充,替换
srcset 绝对不会替换 src 属性。
替换,补充
它为浏览器提供了额外的选项供其选择(如果它有能力)。

图片上缺少 alt 与空的 alt 相同。

正确
空的 alt 属性告诉屏幕阅读器此图片是演示性的。
错误
缺少 alt 不会向屏幕阅读器发出任何信号。