深入研究 CSS 中的 object-fit 和 background-size

已发表: 2022-03-10
快速总结 ↬在本文中,我们将介绍object-fitbackground-size工作原理,何时可以使用它们,以及为什么使用它们,以及一些实际用例和建议。 让我们潜入水中。

我们并不总是能够为 HTML 元素加载不同大小的图像。 如果我们使用与图像纵横比不成比例的宽度和高度,则图像可能会被压缩或拉伸。 这不好,可以使用object-fit for an img元素或使用background-size来解决。

首先,让我们定义问题。 考虑下图:

比较好看的照片和压缩的图像
一张好看的照片,在卡片组件中使用时会被挤压。 (大预览)

为什么会这样?

图像将具有纵横比,浏览器将使用该图像填充包含框。 如果图像的纵横比与为其指定的宽度和高度不同,则结果将是压缩或拉伸的图像。

我们在下图中看到了这一点:

比较好看的照片和拉伸的图像
图像的纵横比与包含框不同,图像被拉伸。 (大预览)

解决方案

当图像的纵横比与包含元素的宽度和高度不一致时,我们并不总是需要添加不同大小的图像。 在深入研究 CSS 解决方案之前,我想向您展示我们过去在照片编辑应用程序中是如何做到这一点的:

在蒙版中裁剪顶部和底部边缘的图像示例
首先,我们将图像垂直居中,然后在蒙版中剪辑。 这会保留图像的纵横比并防止其被挤压。 (大预览)

现在我们了解了它是如何工作的,让我们来看看它在浏览器中是如何工作的。 (剧透警告:这更容易!

CSS object-fit

object-fit属性定义了被替换元素(如imgvideo )的内容应如何调整大小以适应其容器。 object-fit的默认值是fill ,这会导致图像被挤压或拉伸。

让我们回顾一下可能的值。

跳跃后更多! 继续往下看↓

object-fit可能值

object-fit: contain

在这种情况下,图像将调整大小以适应其容器的纵横比。 如果图像的纵横比与容器的不匹配,它将被加黑。

对象拟合:包含
当使用object-fit: contain时,图像将被加信箱或相应地调整大小。 (大预览)

object-fit: cover

在这里,图像也将被调整大小以适应其容器的纵横比,如果图像的纵横比与容器的不匹配,那么它将被裁剪以适应。

适合对象:封面
当使用object-fit: cover时,图像将被剪裁以适应或相应地调整大小。 (大预览)

object-fit: fill

这样,图像将被调整大小以适应其容器的纵横比,如果图像的纵横比与容器的不匹配,它将被压缩或拉伸。 我们不希望那样。

对象拟合:填充
使用object-fit: fill时,图像将被相应地压缩、拉伸或调整大小。 (大预览)

object-fit: none

在这种情况下,图像根本不会调整大小,既不会拉伸也不会压缩。 它的作用类似于cover值,但它不尊重其容器的纵横比。

对象拟合:无
使用object-fit: none时,如果图像尺寸不同,则不会调整图像大小。 (大预览)

除了object-fit之外,我们还有object-position属性,它负责在其容器中定位图像。

object-position可能值

object-position属性的工作方式类似于 CSS 的background-position属性:

对象位置中心,左,右
大多数时候,使用默认值(即 `center` 或 `50% 50%`)。 (大预览)

当包含框的纵横比垂直较大时, topbottom关键字也有效:

对象位置顶部和底部
比较object-position: top (左)和object-position: bottom (右)。 (大预览)

CSS background-size

使用background-size ,第一个区别是我们处理的是背景,而不是 HTML ( img ) 元素。

background-size可能值

background-sizecontain值是auto 、 contains 和cover

background-size: auto

使用auto ,图像将保持其默认大小:

背景尺寸:自动
请记住,默认尺寸有时可能会导致图像模糊(如果太小)。 (大预览)

background-size: cover

在这里,图像将被调整大小以适合容器。 如果纵横比不同,则图像将被遮盖以适应。

背景尺寸:封面
使用background-size: cover时,请务必考虑图像的纵横比。 (大预览)

background-size: contain

在这种情况下,图像将调整大小以适合容器。 如果纵横比关闭,则图像将被加黑,如下例所示:

背景大小:包含
background-size: contain调整图像大小以适合容器。 (大预览)

至于background-position ,它类似于object-position工作方式。 唯一的区别是object-position的默认位置与background-position的默认位置不同。

何时不使用object-fitbackground-size

如果元素或图像具有固定的高度,并且应用了background-size: coverobject-fit: cover ,则会出现图像太宽的点,从而丢失可能影响如何处理的重要细节用户感知图像。

考虑以下示例,其中图像具有固定高度:

 .card__thumb { height: 220px; }
一个图像太宽的例子,因为它有一个固定的高度,而卡片的容器太宽了
右侧显示的图像太宽,因为它具有固定的高度,而卡片的容器太宽。 (大预览)

如果卡片的容器太宽,则会导致我们在右侧看到的内容(图像太宽)。 那是因为我们没有指定纵横比。

对此只有两个修复程序之一。 第一种是使用填充技巧来创建内在比率。

 .card__thumb { position: relative; padding-bottom: 75%; height: 0; } .card__thumb img { position: absolute; left: 0; top: 0; width: 100%; height: 100%; object-fit: cover; }

第二个修复是使用新的aspect-ratio CSS 属性。 使用它,我们可以执行以下操作:

 .card__thumb img { aspect-ratio: 4 / 3; }

注意如果你想了解它,我已经详细地写了关于aspect-ratio属性的文章:“让我们了解 CSS 中的纵横比”。

用例和示例

用户头像

适合object-fit: cover是用户头像。 头像允许的纵横比通常是正方形的。 将图像放在方形容器中可能会扭曲图像。

没有对象拟合和对象拟合的用户头像:封面
没有object-fitobject-fit: cover 。 (大预览)
 .c-avatar { object-fit: cover; }

标志列表

列出企业的客户很重要。 为此,我们经常会使用徽标。 因为徽标会有不同的大小,所以我们需要一种方法来调整它们的大小而不会扭曲它们。

值得庆幸的是, object-fit: contain是一个很好的解决方案。

 .logo__img { width: 150px; height: 80px; object-fit: contain; }
标志列表:Airbnb、Domino's Pizza、Apple Pay、亚马逊
使用object-fit: contain可以帮助我们在不扭曲客户徽标的情况下调整其大小。 (大预览)

文章缩略图

这是一个非常常见的用例。 文章缩略图的容器可能并不总是具有相同纵横比的图像。 这个问题应该首先由内容管理系统 (CMS) 解决,但并非总是如此。

 .article__thumb { object-fit: cover; }
文章缩略图
object-fit: cover的帮助下调整文章缩略图。 (大预览)

英雄背景

在这个用例中,是否使用img元素或 CSS 背景的决定将取决于以下内容:

  • 图片重要吗? 如果由于某种原因禁用了 CSS,我们是否希望用户看到图像?
  • 或者图像的目的仅仅是装饰性的?

根据我们的回答,我们可以决定使用哪个功能。 如果图像很重要

具有英雄背景的用例
让我们假设图像很重要,因为它是一个与食物相关的网站。 (大预览)
 <section class="hero"> <img class="hero__thumb" src="thumb.jpg" alt="" /> </section>
 .hero { position: relative; } .hero__thumb { position: absolute; left: 0; top: 0; width: 100%; height: 100%; object-fit: cover; }

如果图像是装饰性的,我们可以使用background-image

 .hero { position: relative; background-image: linear-gradient(to top, #a34242, rgba(0,0,0,0), url("thumb.jpg"); background-repeat: no-repeat; background-size: cover; }

在这种情况下,CSS 更短。 确保放置在图像上的任何文本都是可读且可访问的。

使用object-fit: contain

您知道可以为img添加背景颜色吗? 当我们也使用object-fit: contain时,我们会从中受益。

在下面的示例中,我们有一个图像网格。 当图像和容器的纵横比不同时,会出现背景色。

 img { object-fit: contain; background-color: #def4fd; }
使用 object-fit 向图像添加背景颜色:包含
我们可以使用object-fit: contain为图像添加背景颜色。 (大预览)

视频元素

您是否曾经需要video作为背景? 如果是这样,那么您可能希望它占据其父级的全部宽度和高度。

 .hero { position: relative; background-color: #def4fd; } .hero__video { position: aboslute; left: 0; top: 0; width: 100%; height: 100%; }
视频未覆盖英雄背景的图
video元素的默认object-fit值为contain 。 正如您在此处看到的,视频没有覆盖英雄背景,即使它具有position: absolutewidth: 100%height: 100% 。 (大预览)

为了使其完全覆盖其父对象的宽度和高度,我们需要覆盖默认的object-fit值:

 .hero__video { /* other styles */ object-fit: cover; }
视频覆盖其父级的整个宽度和高度的图形。
现在视频覆盖了其父级的全部宽度和高度。 (大预览)

结论

正如我们所见, object-fitbackground-size对于处理不同的图像纵横比非常有用。 我们并不总是能够控制为每个图像设置完美的尺寸,而这正是这两个 CSS 功能的亮点所在。

关于在img元素和 CSS 背景之间进行选择的可访问性影响的友好提醒:如果图像纯粹是装饰性的,则选择 CSS 背景。 否则, img更合适。

我希望你发现这篇文章很有用。 感谢您的阅读。