美文网首页
深入理解 CSS 中的 object-fit 和 backgro

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

作者: 涅槃快乐是金 | 来源:发表于2024-09-05 08:47 被阅读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 关键字也可以使用:

    • object-position: top(左侧)和 object-position: bottom(右侧)对比

    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 的一个完美用例就是用户头像。头像的纵横比通常是正方形,将图像放入正方形的容器中可能会导致图像变形。

    • 没有 object-fit 和使用 object-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、Amazon

    使用 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 为图像添加背景颜色。

    视频元素

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

    .hero {
        position: relative;
        background-color: #def4fd;
    }
    
    .hero__video {
        position: absolute;
        left: 0;
        top: 0;
        width: 100%;
        height: 100%;
    }
    
    • 在默认情况下,视频的 object-fit 值是 contain。如图所示,即使视频有 position: absolutewidth: 100%height: 100%,视频仍然无法覆盖整个背景。

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

    .hero__video {
        /* 其他样式 */
        object-fit: cover;
    }
    
    • 现在,视频覆盖了其父容器的全部宽度和高度。

    结论

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

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

    相关文章

      网友评论

          本文标题:深入理解 CSS 中的 object-fit 和 backgro

          本文链接:https://www.haomeiwen.com/subject/azprljtx.html