在这篇文章中,我们将讨论对象匹配和背景尺寸是如何工作的,什么时候可以使用它们,以及为什么,还有一些实际的使用案例和建议。让我们深入了解一下。
我们并不总是能够为一个HTML元素加载不同大小的图像。如果我们使用的宽度和高度与图像的长宽比不成正比,图像可能会被压缩或拉伸。这不是好事,它可以通过img元素的object-fit或使用background-size来解决。

首先,我们来定义这个问题。考虑一下下图。


一张好看的照片,在用于卡片组件时被挤压了。

为什么会出现这种情况?

一张图片会有一个长宽比,浏览器会用该图片来填充包含框。如果图像的长宽比与为其指定的宽度和高度不同,那么结果将是一个被挤压或拉伸的图像。

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


图像的长宽比与包含的盒子不同,图像被拉长了。

解决方案

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


首先,我们要将图像垂直居中,然后夹入一个遮罩。这样可以保留图像的长宽比,防止它被挤压。

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

CSS object-fit

object-fit属性定义了被替换的元素(如img或视频)的内容应如何调整大小以适应其容器。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
在这种情况下,图像根本不会被调整大小,既不会被拉伸也不会被挤压。它的工作原理与封面值类似,但它不尊重其容器的长宽比。


当使用object-fit: none时,如果图片的尺寸不一样,就不会被调整大小。

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

object-position的可能值
object-position属性的工作原理类似于CSS的background-position属性。


大多数情况下,使用默认值(i.e. center or或`50% 50%’)。

当包含箱体的长宽比在垂直方向上较大时,顶部和底部的关键词也能发挥作用。


比较object-position: top (left) 和object-position: bottom (right)。

CSS background-size

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

background-size的可能值
背景尺寸的可能值是auto, contain, 和cover.

background-size: auto
使用auto,图像将保持其默认大小。


请记住,默认尺寸有时可能会导致图像模糊(如果它太小)。

background-size: cover
这里,图像将被调整大小以适应容器。如果长宽比不一样,那么图像将被屏蔽以适应。


当使用background-size: cover时,确保考虑图像的长宽比。

background-size: contain
在这种情况下,图像将被调整大小以适应容器。如果长宽比不对,那么图像将被信箱化,如下例所示。

background-size: 包含调整图像的大小以适应容器。

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

什么时候不使用object-fit或background-size
————————————————-

如果元素或图像被赋予一个固定的高度,并应用了background-size: cover或object-fit: cover,就会出现图像过宽的情况,从而失去重要的细节,可能影响用户对图像的认知。

考虑下面的例子,在这个例子中,图像被赋予一个固定的高度。

.card__thumb {
height: 220px;
}



右边显示的图像太宽,因为它有一个固定的高度,而卡片的容器太宽。

如果卡片的容器太宽,将导致我们在右边看到的情况(图像太宽)。这是因为我们没有指定一个长宽比。

对此,只有两种解决方法中的一种。第一个是使用padding hack来创建一个内在的比例。

  1. .card__thumb {
  2. position: relative;
  3. padding-bottom: 75%;
  4. height: 0;
  5. }
  6. .card__thumb img {
  7. position: absolute;
  8. left: 0;
  9. top: 0;
  10. width: 100%;
  11. height: 100%;
  12. object-fit: cover;
  13. }

第二个解决办法是使用新的宽高比CSS属性。使用它,我们可以做到以下几点。

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

注意:我已经详细地写了关于长宽比属性的文章,如果你想了解它。”让我们来了解一下CSS中的纵横比”。

使用案例和实例

用户头像
对象匹配的一个完美的用例:封面是用户的头像。头像允许的长宽比通常是方形的。将图像放在一个方形的容器中会使图像变形。


没有object-fit和有object-fit的用户头像的比较。
  1. .c-avatar {
  2. object-fit: cover;
  3. }

LOGOS列表

列出一个企业的客户是很重要的。我们经常会使用标识来达到这个目的。因为这些标识会有不同的尺寸,我们需要一种方法来调整它们的尺寸而不使它们变形。

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


使用object-fit:包含可以帮助我们调整客户的标识大小,而不扭曲它们。

文章缩略图

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

  1. .article__thumb {
  2. object-fit: cover;
  3. }

调整文章的缩略图,有一点来自于object-fit: cover适合的帮助。

核心背景

在这个用例中,决定是使用一个img元素还是一个CSS背景将取决于以下几点。

该图像是否重要?如果由于某种原因禁用了CSS,我们是否希望用户看到这个图像?
或者图像的目的只是装饰性的?
根据我们的回答,我们可以决定使用哪种功能。如果图像是重要的。


我们假设图片很重要,因为这是一个与食品有关的网站。
  1. <section class="hero">
  2. <a href="thumb.jpg" class="highslide" onclick="return hs.expand(this,{slideshowGroup:'images'})" target="_blank"><img class="hero__thumb" src="thumb.jpg" alt="" /></a>
  3. </section>
  4. .hero {
  5. position: relative;
  6. }
  7. .hero__thumb {
  8. position: absolute;
  9. left: 0;
  10. top: 0;
  11. width: 100%;
  12. height: 100%;
  13. object-fit: cover;
  14. }

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

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

在这种情况下,CSS比较短。确保放在图片上的任何文字都是可读的,并且是可访问的。

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

在下面的例子中,我们有一个图片的网格。当图像和容器的长宽比不同时,背景色就会出现。

  1. img {
  2. object-fit: contain;
  3. background-color: #def4fd;
  4. }

我们可以使用object-fit: contain来给图片添加背景色。

视频元素

你是否曾经需要一个视频作为背景?如果是这样,那么你可能希望它占据其父本的全部宽度和高度。

  1. .hero {
  2. position: relative;
  3. background-color: #def4fd;
  4. }
  5. .hero__video {
  6. position: aboslute;
  7. left: 0;
  8. top: 0;
  9. width: 100%;
  10. height: 100%;
  11. }

视频元素的默认对象拟合值是包含。正如你在这里看到的,视频并没有覆盖英雄的背景,尽管它的position: absolute, width: 100%, height: 100%。

为了使它完全覆盖其父体的宽度和高度,我们需要覆盖默认的object-fit适合值。

  1. .hero__video {
  2. /* other styles */
  3. object-fit: cover;
  4. }

现在,视频覆盖了其父体的全部宽度和高度。

总结

正如我们所看到的,object-fit和background-size对于处理不同的图像长宽比都非常有用。我们并不总是能够控制为每张图片设置完美的尺寸,而这正是这两个CSS特性的闪光点。

友好地提醒一下在img元素和CSS背景之间选择的可访问性问题。如果图像纯粹是装饰性的,那么就选择CSS背景。否则,img元素更合适。

我希望你觉得这篇文章很有用。谢谢你的阅读。