深入研究 CSS 中的 object-fit 和 background-size

已發表: 2022-03-10
快速總結↬在本文中,我們將介紹object-fitbackground-size工作原理,何時可以使用它們,以及為什麼使用它們,以及一些實際用例和建議。 讓我們潛入水中。

我們並不總是能夠為 HTML 元素加載不同大小的圖像。 如果我們使用與圖像縱橫比不成比例的寬度和高度,則圖像可能會被壓縮或拉伸。 這不好,可以使用object-fit for an img元素或使用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屬性:

對象位置中心,左,右
大多數時候,使用默認值(即 `center` 或 `50% 50%`)。 (大預覽)

當包含框的縱橫比垂直較大時, topbottom關鍵字也有效:

對象位置頂部和底部
比較object-position: top (左)和object-position: bottom (右)。 (大預覽)

CSS background-size

使用background-size ,第一個區別是我們處理的是背景,而不是 HTML ( img ) 元素。

background-size可能值

background-sizecontain值是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-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; }

注意如果你想了解它,我已經詳細地寫了關於aspect-ratio屬性的文章:“讓我們了解 CSS 中的縱橫比”。

用例和示例

用戶頭像

適合object-fit: cover是用戶頭像。 頭像允許的縱橫比通常是正方形的。 將圖像放在方形容器中可能會扭曲圖像。

沒有對象擬合和對象擬合的用戶頭像:封面
沒有object-fitobject-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、亞馬遜
使用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 向圖像添加背景顏色:包含
我們可以使用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: absolutewidth: 100%height: 100% 。 (大預覽)

為了使其完全覆蓋其父對象的寬度和高度,我們需要覆蓋默認的object-fit值:

 .hero__video { /* other styles */ object-fit: cover; }
視頻覆蓋其父級的整個寬度和高度的圖形。
現在視頻覆蓋了其父級的全部寬度和高度。 (大預覽)

結論

正如我們所見, object-fitbackground-size對於處理不同的圖像縱橫比非常有用。 我們並不總是能夠控制為每個圖像設置完美的尺寸,而這正是這兩個 CSS 功能的亮點所在。

關於在img元素和 CSS 背景之間進行選擇的可訪問性影響的友好提醒:如果圖像純粹是裝飾性的,則選擇 CSS 背景。 否則, img更合適。

我希望你發現這篇文章很有用。 感謝您的閱讀。