[譯] CSS min-content、max-content 和 fit-content 屬性值介紹

原文連接:Intrinsic Sizing In CSS,by Ahmad Shadeedcss

CSS 中存在兩種尺寸:內在尺寸(intrinsic)和外在尺寸(extrinsic)。爲元素的 widthheight 設置的固定屬性值,就是指外部尺寸,這是最經常使用的方式。而內部尺寸,則是由元素包含的內容量決定的。html

本篇將會詳細介紹控制內在尺寸的每一個值,看看它們的使用能帶來什麼好處。同時,我還會舉例說明這些值與 CSS Grid 佈局/其餘屬性如何結合使用。sql

外在尺寸

外在尺寸是指用精確的值指定元素尺寸。舉個例子:瀏覽器

.c-button {
    width: 100px;
}
複製代碼

這個按鈕的尺寸是 100px,這就是外在尺寸了。再好比一個 <div> 元素,它默認是個塊級元素,就是說它的寬默認等於 100% 父元素的寬。app

有時,咱們想要根據元素實際的內容來設置尺寸,這個時候,使用外在尺寸就沒有用了。接下來,咱們來看看如何是用內在屬性值來解決問題的吧!ide

min-content

min-content 值表示內在最小寬度(譯註:這裏說的不許確,也能夠是「最小高度」,所以應該稱爲「最小尺寸」),它等於元素內容裏最長的那個單詞寬度。函數

CSS Working Group (CSSWG) 的說法是:佈局

The inline size that would fit around its contents if all soft wrap opportunities within the box were taken.post

坦率地講,我太理解 CSSWG 關於這個概念的定義。我本身是這麼理解的:我在元素的周圍包裹了一個框,元素內容(不少單詞)會所以而折行,這個框的寬度將等於元素中最長的那個單詞。若是我這裏表述有誤的話,但願你們來更正。ui

舉一個例子,有一個標題元素:

<h2>A title for an awesome article</h2>
複製代碼
h2 {
  width: min-content;
}
複製代碼

intrinsic-sizing-1.png

你們能夠看見,當元素的 width 設置成 min-content 後,其寬度等於最長單詞的寬度,也就是這裏的「awesome」。

image.png

A pen by Ahmad Shadeed

max-content

max-content 表示元素的內在首選寬度(intrinsic preferred width),它等於元素內容的寬。

還舉一個標題元素的例子,不過此次改用 max-content 了:

h2 {
  width: max-content;
}
複製代碼


intrinsic-sizing-2.png

注意觀察,元素寬度等於標題寬度了。這個寬度是動態的,隨着標題內容的改變,max-content 所表明的值也相應改變。

fit-cotent

這個屬性能夠當作是 min-contentmax-content 的結合。搜索的時候,我發現 Stackoverflow 上的這個回答我很喜歡:

fit-content 默許使用 max-content;若是 available < max-content,那就使用 available;若是 available < min-content,那就使用 min-content

畫一個流程圖表示,就是下面這樣的:

intrinsic-sizing-3.png

注意,這裏的「available」表示元素在視口中的可用空間。

🤔 譯註
上面的流程圖跟 Stackoverflow  上的回答比起來,並不十分清晰,反而是後者更容易理解起來。關於 Stackoverflow  上的回答個人理解以下:

fit-content 屬性到底取用何值,跟當前元素的可用空間(available)是緊密相關的。

1. 若是可用空間充足,那就用你元素的 max-conetnt 又何妨,反正夠裝你的。
2. 若是可用空間不夠充裕,比 max-conetnt 小點,那就得用可用空間的值了,這才顯得合適(fit),不會致使內容越界。
3. 若是可用空間不多,甚至比 min-conetnt 還小,那很差意思,得用 min-content 了,否則顯示會很難看,就不合適了。

讓咱們舉個例子看看它是如何工做的。

h2 {
    width: fit-content;
}
複製代碼

查看下面的 GIF 圖,觀察標題尺寸是如何隨着視口的變化作調整的。

fit-content.gif

咱們再回顧一下關於 fit-content 的知識:若是當前的可用空間比 max-content 還大的話,width 就等於 max-content;若是可用空間比 max-content 的小的話,那麼 width 就等於可用空間的寬了;最後,若是可用空間比 min-content 還小,那麼 width 就等於 min-content

到目前爲止,我解釋完了每個內在值。讓咱們轉向真實的案例來看下吧。

使用案例

<figure><caption>

如今咱們假設有一個帶 <caption><figure>,由於它是個塊級元素,所以默認等於 100% 父元素寬度的。

<figure>
    <img src="blueberry-cheesecake-x.png" alt="">
    <figcaption>..</figcaption>
</figure>
複製代碼

intrinsic-figure-0.png

咱們預期的行爲是但願 <figure> 包裹圖像的,使用 max-content 就能取得這些效果,讓 <figure> 與內容(最大)寬度同樣。

figure {
    width: max-content;
    margin-left: auto;
    margin-right: auto;
}
複製代碼

intrinsic-figure.png

但有一個問題,若是圖片比視口範圍還大的話,這時由於 <figure> 的寬度就等於圖片的寬度,所以就會致使水平滾動條的出現。

intrinsic-figure-2.png

爲了解決這個問題,咱們就要爲圖片使用 fit-content 了。它不會讓大圖片超出視口以外顯示。

figure {
    width: fit-content;
}
複製代碼

image.png

A pen by Ahmad Shadeed

帶分隔符的標題

在這個例子裏,「Top Stories」要折成兩行顯示。寬度仍是動態的,就是說無論實際標題如何,都須要折行。爲了實現這個效果,咱們可使用 min-content

span {
    width: min-content;
}
複製代碼

image.png

A pen by Ahmad Shadeed

帶下劃線的標題

內在值的另外一個有趣的用例是帶邊框的標題,要求邊框跟標題內容同樣長。考慮下圖:

intrinsic-title.png

注意,標題是個塊狀元素。爲了獲得上述的效果,之前的作法是將內容包裝在 <span> 標籤裏,給 <span> 設置邊框效果。

<h2><span>A title for an awesome article</span></h2>
複製代碼
<h2><span>A title for an awesome article</span></h2>
複製代碼

固然,咱們還能夠藉助 fit-content 來讓標題寬度與內容同樣長。

h2 {
    width: fit-content;
    margin-left: auto; /* For centering */
    margin-left: auto; /* For centering */
    border-bottom: 2px solid #e2deed;
}
複製代碼

image.png

A pen by Ahmad Shadeed

導航


若是一個頁面導航的寬度是基於內容的。那麼,能夠經過使用 max-content,輕鬆實現效果:

.c-nav {
    width: max-content;
}
複製代碼

Demo

Todo 列表

在網上找內在值的使用案例的時候,看到了 一篇文章,將我吸引了。

考慮下面的例子:

這個 Todo 列表包含:頁眉、列表和頁腳。

無論有多少列表項,中間部分的高度都應該是 100% - header - footer。爲了實現這個效果,咱們能夠將 CSS Grid 與 min-content 搭配使用。

.c-todo {
  display: grid;
  grid-template-rows: min-content auto min-content;
  height: 100vh;
}
複製代碼


你可能想知道,若是咱們不使用 min-content,會是什麼結果呢?好吧,來看看:

聊天窗口

設想構建一個聊天程序。在下面的示例裏,佈局結構與 Todo 列表很是類似。當沒有\聊天記錄,而且沒有使用 min-content 時,就會致使佈局遭到破壞。

Demo

Hero

假設咱們頁面 <header> 裏包含一個 Hero 組件。咱們的目標是讓這個 Hero 組件實現動態佈局,佔據一屏裏剩下的空間。

.c-section {
    display: grid;
    grid-template-rows: min-content 1fr;
}
複製代碼

有兩行內容,第一行使用的是最小內容高度,而第二行則能夠擴展、填充完剩下的可用空間。

image.png

A pen by Ahmad Shadeed

Sidebar 和 Main

我老是想知道爲何咱們非要給側邊欄一個固定寬度呢。若是它的寬度是基於內容的呢?好比說,它有一個基於內容的最小寬度和一個最大寬度?咱們來試試。

<div class="wrapper">
  <aside></aside>
  <main></main>
</div>
複製代碼
.wrapper {
    grid-template-columns: fit-content(150px) 1fr;
    grid-gap: 1rem;
}
複製代碼

經過使用 CSS Grid fit-content 函數,咱們能夠確保側邊欄的寬度不會超過 150px,而且能夠在內容很短的狀況下縮小到 150px 如下。

當側邊欄的內容不多時,它會縮小一點:

🤔譯註
這的 fit-content() 文中並無講到。能夠簡單把它理解爲一個公式:min(max-content, max(min-content, argument)),即

先將咱們帶入的參數 argument(即這裏的 150px)與 min-content 比較 取大 的那一個,而後將獲得的數與 max-content 比較 取小 的那一個,最終的比較結果就是 fit-content() 的返回值。

也就是說,根據 argument 的不一樣,fit-content() 會有三個可能的返回值:

1. 當 argument 比 max-content 大時,fit-content() 返回的是 max-content
2. 當 argument 比 max-content 小一點時,fit-content() 返回的是 argument
3. 當 argument 比 min-content 還小時,fit-content() 返回的是 min-content

更多信息,查看 MDN 上的 fit-content() 文檔

再來看文中表述:

1. 側邊欄的寬度不會超過 150px:這是說 argument 的值比 max-content 小,有兩種結果——argument(即 150px。對應狀況 2) 和 min-content(對應狀況 3)。
2. 內容很短的狀況下縮小到 150px 如下:這是說 argument 的值比 max-content 大的狀況,這時候返回的是 max-content(對應狀況 1)。

標題和描述

咱們有一個標題和一個描述文本。描述文字的寬度不能超過主標題的寬度。對我來講,這是一個有趣的用例,我之前認爲它不可能僅用 CSS 就能實現。

看下下面的模型。

爲了實現上述功能,咱們須要將 min-content 設置爲包裝元素的寬度,而爲標題元素設置 width: max-content

section {
  width: min-content;
  margin: 0 auto;
  text-align: center;
}

h2 {
  width: max-content;
}
複製代碼

請注意,上面代碼須要在移動端作些調整額,不然可能會致使致使水平滾動條的出現。

image.png

A pen by Ahmad Shadeed

瀏覽器兼容性

根據 Can I Use 數據,除了 Microsoft Edge (EdgeHTML) 以外的全部主流瀏覽器都支持內在值的設置了。

注意:Microsoft Edge (Chromium)  從發佈的第一個版本(79)就已經支持了。

image.png

(正文完)


廣告時間(長期有效)

我有一位好朋友開了一間貓舍,在此幫她宣傳一下。如今貓舍裏養的都是布偶貓。若是你也是個愛貓人士而且有須要的話,不妨掃一掃她的【閒魚】二維碼。不買也沒關係,看看也行。

(完)

相關文章
相關標籤/搜索