深入研究 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: cover
在这里,图像也将被调整大小以适应其容器的纵横比,如果图像的纵横比与容器的不匹配,那么它将被裁剪以适应。
object-fit: fill
这样,图像将被调整大小以适应其容器的纵横比,如果图像的纵横比与容器的不匹配,它将被压缩或拉伸。 我们不希望那样。
object-fit: none
在这种情况下,图像根本不会调整大小,既不会拉伸也不会压缩。 它的作用类似于cover
值,但它不尊重其容器的纵横比。
除了object-fit
之外,我们还有object-position
属性,它负责在其容器中定位图像。
object-position
可能值
object-position
属性的工作方式类似于 CSS 的background-position
属性:
当包含框的纵横比垂直较大时, top
和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: 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
是用户头像。 头像允许的纵横比通常是正方形的。 将图像放在方形容器中可能会扭曲图像。
.c-avatar { object-fit: cover; }
标志列表
列出企业的客户很重要。 为此,我们经常会使用徽标。 因为徽标会有不同的大小,所以我们需要一种方法来调整它们的大小而不会扭曲它们。
值得庆幸的是, object-fit: contain
是一个很好的解决方案。
.logo__img { width: 150px; height: 80px; object-fit: contain; }
文章缩略图
这是一个非常常见的用例。 文章缩略图的容器可能并不总是具有相同纵横比的图像。 这个问题应该首先由内容管理系统 (CMS) 解决,但并非总是如此。
.article__thumb { 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; }
视频元素
您是否曾经需要video
作为背景? 如果是这样,那么您可能希望它占据其父级的全部宽度和高度。
.hero { position: relative; background-color: #def4fd; } .hero__video { position: aboslute; left: 0; top: 0; width: 100%; height: 100%; }
为了使其完全覆盖其父对象的宽度和高度,我们需要覆盖默认的object-fit
值:
.hero__video { /* other styles */ object-fit: cover; }
结论
正如我们所见, object-fit
和background-size
对于处理不同的图像纵横比非常有用。 我们并不总是能够控制为每个图像设置完美的尺寸,而这正是这两个 CSS 功能的亮点所在。
关于在img
元素和 CSS 背景之间进行选择的可访问性影响的友好提醒:如果图像纯粹是装饰性的,则选择 CSS 背景。 否则, img
更合适。
我希望你发现这篇文章很有用。 感谢您的阅读。