CSS 新的長度單位 `fr` 你知道麼?

前端外刊評論發表於2017-06-21

本文譯自:An Introduction to the fr CSS unit。首發知乎專欄「前端外刊評論」,介紹了 CSS Grid 規範中引入的一個新的長度單位 fr,我們一起來看看到底是怎麼回事吧,譯文走起!

關於 CSS Grid 的激烈討論到處都是,但我發現很少有討論 fr 這個新的 CSS 長度單位(規範在這裡)的文章。

為了講清楚,先從一個典型的案例開始,我們看下面的例子,用 CSS 建立一個網格,這個網格一行四列,每列等寬。

<div class="grid">
  <div class="column"></div>
  <div class="column"></div>
  <div class="column"></div>
  <div class="column"></div>
</div>複製程式碼
.grid {
  display: grid;
  grid-template-columns: repeat(4, 25%);
  grid-column-gap: 10px;
}複製程式碼

CSS 新的長度單位 `fr` 你知道麼?

codepen.io

grid-template-columns 裡我們使用了 repeat(),如果你已經知道了 repeat() 的功能可以跳過本段。它是 CSS Grid 引入的最有愛的特性之一!它是一種縮寫方式,本質就是為了減少我們重複書寫多個值的問題。本來我們可以直接寫 grid-template-columns: 25% 25% 25% 25%;,但用 repeat() 看上去更清晰明瞭,尤其是有很多冗長的寬度表示時(比如 minmax() 表示式)。

repeat 的語法如下:

repeat(number of columns/rows, the column width we want);複製程式碼

可能你還沒發現,目前我們的 CSS 程式碼是有點問題的。

首先,為了使用這個可愛的函式,我們必須做數學題。必須計算一下分成4欄每欄的寬度是百分之多少,不錯,這裡是 25%。這道題目還算簡單,但是如果複雜點我們就需要讓瀏覽器幫我們做。還好我們有 calc() 函式,於是我們的答案可以是 repeat(4, calc(100%/4)),看起來有點複雜呵……不過還有另外一個致命問題:

這個問題就是元素溢位了。4 個 25% 寬的欄加上 10px 的 grid-column-gap 超過了 100%。百分比的工作模式沒有問題,但顯然結果不是我們想要的。我們希望程式碼表達的是:每欄的寬度是總寬度的(viewport 的寬度)25%,欄與欄之間的有 10px 的間距。差別很微妙,佈局就很尷尬了。

外刊君:repeat(4, calc((100% - 10px * 3)/ 4)) 這樣可以工作!

一不小心我們搞出了滾動條:

CSS 新的長度單位 `fr` 你知道麼?

codepen.io

這個時候 fr 就持證上崗服務我們了。

在定義網格時,fr 的用法與其他 CSS 長度單位 %pxem 等是一樣的。用這個神奇的新單位重寫一下程式碼:

.grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  grid-column-gap: 10px;
}複製程式碼

CSS 新的長度單位 `fr` 你知道麼?

codepen.io

demo 看起來沒啥變化,四欄等寬(就是 1/4 或者是 25%)。但是,注意!橫向的 overflow 消失了。每個欄的寬度設定為 1fr 後,三個 10px 的間隙首先從總寬度減去,再計算每個欄的寬度!

你可能會bibi說為啥我非要用這個新的 CSS 單位,我繼續堅持使用百分比或者 px 有什麼不好?好吧,我們再看一個更復雜的例子,顯然 fr 是更好的方案。在下面這個例子中,最左邊一個有一個導航欄,然後右緊跟著20個 column:

CSS 新的長度單位 `fr` 你知道麼?

這種“切圖”需求很常見啊,如果不使用 fr,我們只能選擇使用額外的 grid 或者 calc 來實現。我們必須像下面這樣思考:

欄的寬度 = (viewport 的寬度 - nav 的寬度) /  欄的數量  * 100%複製程式碼

是,這沒問題,但是很醜很痛有沒有?一旦我們更改 nav 的寬度,需要再做一遍數學題。所以啊, fr 這個單位完美處理這個問題,程式碼可讀性很強有沒有?

.grid {
  display: grid;
  grid-template-columns: 250px repeat(12, 1fr);
  grid-column-gap: 10px;
}複製程式碼

CSS 新的長度單位 `fr` 你知道麼?

codepen.io

我們的方案就是給第1欄設定一個固定寬度,然後重複建立20個欄“平分剩下的自由空間”(從規範的標準解釋是這樣)。不需要做任何的數學題!易讀,最左邊的 nav 可以隨意更改,剩下的20個欄會自動伸縮。

好了,一點點不動腦的工作讓我們的介面更容易維護了。就算將來的某個時候再來看程式碼也很清晰,說簡單點,就算辭職了,後來的“切圖仔”也不用跳坑!

歡迎微博知乎搜尋「前端外刊評論」微信搜尋 FrontendMagazine 關注外刊君。

CSS 新的長度單位 `fr` 你知道麼?

相關文章