深入研究 CSS 中的 object-fit 和 background-size
已发表: 2022-03-10object-fit和background-size工作原理,何时可以使用它们,以及为什么使用它们,以及一些实际用例和建议。 让我们潜入水中。 我们并不总是能够为 HTML 元素加载不同大小的图像。 如果我们使用与图像纵横比不成比例的宽度和高度,则图像可能会被压缩或拉伸。 这不好,可以使用object-fit for an img元素或使用background-size来解决。
首先,让我们定义问题。 考虑下图:

为什么会这样?
图像将具有纵横比,浏览器将使用该图像填充包含框。 如果图像的纵横比与为其指定的宽度和高度不同,则结果将是压缩或拉伸的图像。
我们在下图中看到了这一点:

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

现在我们了解了它是如何工作的,让我们来看看它在浏览器中是如何工作的。 (剧透警告:这更容易! )
CSS object-fit
object-fit属性定义了被替换元素(如img或video )的内容应如何调整大小以适应其容器。 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属性:

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

object-position: top (左)和object-position: bottom (右)。 (大预览) CSS background-size
使用background-size ,第一个区别是我们处理的是背景,而不是 HTML ( img ) 元素。
background-size可能值
background-size的contain值是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-fit或background-size
如果元素或图像具有固定的高度,并且应用了background-size: cover或object-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-fit和object-fit: cover 。 (大预览) .c-avatar { object-fit: cover; }标志列表
列出企业的客户很重要。 为此,我们经常会使用徽标。 因为徽标会有不同的大小,所以我们需要一种方法来调整它们的大小而不会扭曲它们。
值得庆幸的是, object-fit: contain是一个很好的解决方案。
.logo__img { width: 150px; height: 80px; object-fit: contain; } 
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: 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: absolute 、 width: 100%和height: 100% 。 (大预览) 为了使其完全覆盖其父对象的宽度和高度,我们需要覆盖默认的object-fit值:
.hero__video { /* other styles */ object-fit: cover; } 
结论
正如我们所见, object-fit和background-size对于处理不同的图像纵横比非常有用。 我们并不总是能够控制为每个图像设置完美的尺寸,而这正是这两个 CSS 功能的亮点所在。
关于在img元素和 CSS 背景之间进行选择的可访问性影响的友好提醒:如果图像纯粹是装饰性的,则选择 CSS 背景。 否则, img更合适。
我希望你发现这篇文章很有用。 感谢您的阅读。
