深入理解 CSS 中的 object-fit 和 backgro

2024-09-05  本文已影响0人  涅槃快乐是金

我们并不总是能够为 HTML 元素加载不同尺寸的图像。如果我们使用的宽度和高度不符合图像的纵横比,图像可能会被压缩或拉伸。这不是一个好的结果,不过我们可以通过对 img 元素使用 object-fit 或使用 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 属性类似:

image.png
大多数情况下,默认值会被使用(即 center50% 50%

当容器的纵横比在垂直方向上更大时,topbottom 关键字也可以使用:

CSS background-size

使用 background-size 时,主要区别在于我们处理的是背景,而不是 HTML 的 img 元素。

background-size 的可能值

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;
}

用例与示例

用户头像

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 背景取决于以下问题:

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

<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;
}

视频元素

你是否曾需要将视频用作背景?如果是,那么你可能希望它占据父容器的全部宽度和高度。

.hero {
    position: relative;
    background-color: #def4fd;
}

.hero__video {
    position: absolute;
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
}

要让视频完全覆盖其父容器的宽度和高度,我们需要覆盖默认的 object-fit 值:

.hero__video {
    /* 其他样式 */
    object-fit: cover;
}

结论

正如我们所见,object-fitbackground-size 在处理不同图像纵横比时非常有用。我们不总是能够控制每个图像的完美尺寸,这时这两个 CSS 功能就发挥了作用。

在选择 img 元素和 CSS 背景之间时要注意可访问性。如果图像是纯装饰性的,使用 CSS 背景更合适;否则,使用 img 更合适。

上一篇下一篇

猜你喜欢

热点阅读