[譯]使用 CSS Grid:以相容不支援柵格化佈局的瀏覽器

0x7e2發表於2017-12-24

摘要

當使用任何 CSS 的新特性的時候,瀏覽器的相容問題都必須去解決。與 Flexbox 和 CSS Grid 一樣,在使用 CSS 新特性佈局時,相容性比效能增強更值得考慮。

在這篇文章中,我將探索現今處理瀏覽器相容問題的方法。為了讓我們現在就用上 CSS 的新特性,我們可以做出哪些努力,仍然給那些不支援新特性的瀏覽器提供很好的體驗?

我們說的支援是什麼?

在闡明如何在去支援那些本身不支援網格的瀏覽器之前,很有必要搞明白 支援 的含義。支援也許是站點必須在列表中的瀏覽器上看起來完全相同。這可能意味著對於所有的瀏覽器,你都可以不用去做一些收尾工作。這可能意味著你在測試這些瀏覽器的時候對他們能獲得一致的體驗而感到十分高興。

一個相關的問題就是**你怎麼確定要支援的瀏覽器列表?**即使是一個全新的網站,也不應該拍腦袋就定了。對於今天的大多數的企業都曾經建立過網站。你可能有一些分析工具用於檢視網站支援的瀏覽器,但是要注意這些工具不會檢測對移動端的支援情況。如果在較小螢幕上表現不佳,人們便不會在手機上訪問這個網站!

如果沒有任何的分析工具,你可以在 Can I Use 上面匯入你所在位置的資料。

在 Can I Use 上可以匯入你所在位置的使用情況資料

Can I Use 這個網站上,你可以匯入所在位置的使用情況資料。 (預覽大圖)

同樣值得在這裡牢記網站的目標。例如,希望吸引生活在印度等新興市場的訪問者的網站應該確保能在這些國家使用者使用的瀏覽器中正常執行。

我僅僅只需要擔心舊瀏覽器嗎?

截止發稿,Edge,Chrome,Firefox,Opera,Safari,iOS Safari 都支援了網格佈局。

IE10 和 IE11 支援帶有 -ms 字首的原始規格。對於你正在使用的 瀏覽器來說:

  • Internet Explorer 9(如果僅考慮新的規範,則為IE 11及更低版本)
  • Edge 15 及以下
  • Firefox 52 之前的版本
  • Safari 和 iOS Safari 10.1 版本之前
  • Chrome 57 之前的版本
  • Samsung Internet 6.2 之前的版本

然而,正如上一節所述,這些流行的桌面端和移動端瀏覽器在新興市場中已經更常用。這些瀏覽器還不支援網格佈局。比如說從世界範圍來看,UC 瀏覽器佔用了 8.1% 的流量,儼然是世界第三大流行的瀏覽器。但是如果碰巧你住在美國或者歐洲,可能你從來都沒有聽說過。

[譯]使用 CSS Grid:以相容不支援柵格化佈局的瀏覽器

(圖片來源) (預覽大圖)

UC 瀏覽器不支援網格佈局。它不僅針對低功耗裝置進行了優化,也適用於那些流量費昂貴地區的使用者。這是我們在開始規劃支援的一個重要考慮因素。

有沒有 CSS Grid 的 Polyfill(墊片)?

在第一次遇到 CSS Grid 的時候,一個顯而易見的問題是:“我可以使用 polyfill 嗎?”不幸的是,即使有這樣的好事,對於整個佈局來說,一個神奇的 polyfill 既不太可能出現,也不是一個好主意。

使用舊的佈局方式,網格幾乎做不到這一點。所以,為了在不支援的瀏覽器中複製網格佈局,需要在 JavaScript 中做很多的工作。即使在資源充足的計算機上,使用了快速渲染引擎,在計算高度和元素的定位方面還是可能會帶來一些令人生厭的體驗。我們已經知道,不支援網格的瀏覽器是新興市場上低功耗裝置上最常見的 較老,或者較慢的瀏覽器。為什麼硬要在這些裝置上放一堆 JavaScript 呢?

不要搜尋一個 polyfill,而是要考慮如何使用網格佈局為那些不支援的瀏覽器提供更好的體驗。在支援的瀏覽器上,使用網格可以用最少的 CSS 創造複雜的佈局,但同時仍然要為那些不支援的瀏覽器提供良好的體驗。這樣會比僅僅在這個問題上丟擲一個 polyfill 多一些工作,但是這樣做的話,你可以保證能提供良好的體驗,反而讓網站在所有的地方顯示相同不是最重要的目標。

網格佈局降級方案

那麼,我們如何為正在使用的裝置和瀏覽器提供定製的支援?事實證明,CSS 中有你要的答案。

瀏覽器忽略那些他們不懂的 CSS

圖片的第一部分是瀏覽器略過他們不懂的 CSS。如果一個瀏覽器不支援 CSS Grid 佈局,遇到 grid-template-columns 屬性的時候,他不知道這是什麼東西,所以就會跳過這行繼續解析下面的內容。

這就意味著你需要用一些舊的 CSS,就像你過去那樣,使用 float 或者 display: table-cell 在古老瀏覽器中實現網格樣式的佈局。不支援網格佈局的瀏覽器將使用此佈局並且忽略所有的網格宣告。支援網格佈局的瀏覽器將會繼續尋找網格指令並且應用他們。這一點上,我們需要考慮如果使用其他佈局方法的專案成為網格專案的時候會發生什麼情況。

新佈局相容舊佈局

規範規定了如果你的頁面上有使用其他佈局方式定位的元素的時候,網格將會如何處理。

使用了浮動(float)或清除(clear)屬性的元素,再應用網格成為網格元素的話,將不再表現為浮動或清除,就像從沒用過它們一樣。在下一個 CodePen 中刪除應用了 .grid 類的所有屬性,你可以看到我們所有的專案是如何浮動的,第三個專案是如何清除浮動的。但是在網格佈局中,這將被忽略。

可以看下 rachelandrew (@rachelandrew) 在 CodePen 寫的這個 Pen 使用 display: grid 覆蓋 float 和 clear

inline-block 同樣也是如此。inline-block 可以設定給子項,但是隻要父視窗應用了 display: grid,那麼 inline-block 將失效。

我經常使用 CSS display: table-cell 來建立一個列布局,並在非支援網格的瀏覽器中對齊專案,因為這樣 vertical-align 屬性可以生效。

如果你以前不知道, 閱讀 CSS 佈局的反英雄 — “display:table”。我不建議你現在使用這個作為主要的佈局方式,但是它可以作為一個非常有用的回退方案。

當你使用 display: table-cell 建立列,CSS 將建立所謂的 匿名框 。這些是表格的缺失部分 —— 真正的 HTML 表格中的單元格將在 table 元素裡邊的 tr 元素內。匿名框基本上解決了這些失蹤的父元素。如果你的 table-cell 元素變成了一個網格元素。這樣這個元素的 table 顯示同樣會失效,就像什麼也沒有發生。

vertical-align 屬性在網格佈局中仍然不適用。因此如果你可以在 CSS 表格佈局或 inline-block中使用它,則可以安全的忽略該屬性,盡情使用網格佈局的框對齊方式。你可以在下一個 CodePen 中看到一個使用 CSS Grid 覆蓋 display:table-cellvertical-align 的佈局。

可以看下 rachelandrew (@rachelandrew) 在 CodePen 寫的這個 Pen display: grid 覆蓋 display: table-cell 和 vertical-align

你同樣可以使用 Flexbox 作為一個回退方案,一旦你在一個使用 flex 屬性或者獨立的 flex-growflex-shrink 或者 flex-basis 屬性的元素上使用 grid 佈局,它們(flex 等)同樣會失效。

最後,請不要忘記多列布局在某種情況下可以作為一個回退方案。當對卡片或影象進行佈局時,它將以列而不是行來顯示每一項。但是在某些情況下可能是有用的。在容器上應用 column-count 或者 column-width 使其成為多列容器。然後應用 display:grid 將忽略 column-* 行為。

特徵查詢

其他大多數佈局方式中,大多都只是針對單個專案而不是其容器。例如在浮動佈局中,我們有一堆給定了百分比寬度的專案,為其設定左浮動(float: left)。這將讓他們排列在一起。只要總數不超過父容器寬度的 100%,我們就可以實現類似網格的效果。

.grid > * {
  float: left;  
  width: 33%;
}
複製程式碼

給定寬度的浮動元素給我們類似網格的感覺

給定寬度的浮動元素給我們類似網格的感覺。 (預覽大圖)

如果我們把佈局方式換成 CSS Grid 佈局,在父級上建立一個網格。我們僅僅需要做的就是指定這些元素能橫跨多少列。

.grid {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  grid-auto-rows: 100px;
  grid-gap: 20px;
}
複製程式碼

在我們以前的佈局中,我們為浮動元素給定了大小。在新的佈局中,這些元素變成了網格元素,通常我們並不會給這些元素大小,因為可以從跨過的網格軌跡上確定。

在這裡,我們只是能夠 用另一個覆蓋一個佈局的方式 來解決問題。在浮動佈局的例子中,一旦指定了百分比大小的元素成為網格元素的時候,大小就會變成它所在網格區域的百分比,而不是整個容器的百分比。你可以使用 Firefox Grid Inspector 來高亮顯示這些行 —— 這些元素現在被擠壓到了網格單元的一側。

在網格佈局中,寬度將成為網格區域的百分比

在網格佈局中,寬度將成為網格區域的百分比。(預覽大圖)

這是特徵查詢可以發揮作用的地方。特徵查詢類似於媒體查詢,不是去檢查裝置的寬度和方向,而是去檢查瀏覽器是否支援 CSS 功能。

在我們想要變成網格佈局的浮動佈局示例中,我們只需要在特徵查詢中內部重寫一個東西 —— 我們想要將寬度重新設定為自動。

檢視 @rachelandrewCodePen 寫的這個 Pen:display: 特性查詢 demo

你需要重寫多少用於不支援瀏覽器的 CSS,取決於你要為這些較舊的瀏覽器建立多少不同的佈局。

IE10 和 11 版本的網格佈局

雖然 Edge 瀏覽器現在已經升級到支援現代網格佈局,但是 IE10 和 IE11 只支援像早期版本那樣,在這些瀏覽器加 -ms 字首的寫法。我們今天所知道的網格規範最初來自於微軟。對這個老的實現方案,我們不是不高興。我們應該很高興他們開始了這個過程,首先是給了我們網格。你可以從這篇文章瞭解更多:CSS 網格的故事,來自它的創作者

如上所述,你可能決定為 IE10 和 11 提供基於浮動或其他佈局型別的回退方法。這個功能也可以正常工作,就像 IE10 和 11 不支援功能查詢一樣。只要使用這些功能來覆蓋舊的方法來檢查其支援情況,然後建立支援瀏覽器的版本,IE10 和 11 將使用較舊的方法。

你依舊可以使用 -ms-grid 版本來建立回退方法。然而這個字首的版本和現代網格佈局不一樣,它是第一個版本,並且也是實驗版本。自從運用五年左右以來,情況已經發生了變化。這意味著你不能只使用 autoprefixer 來新增字首,這種方法可能會讓 IE10 和 11 的使用者體驗比你不做任何處理還要糟。相反,你需要使用這個不同的、更有先的規範來建立一個佈局。

要注意的要點如下:

  1. 如果沒有自動放置,你需要使用基於行的定位將每一個元素放在網格上。
  2. grid-template-areas ascii-art 方法不是實現的一部分。
  3. 不要設定網格間隙的屬性
  4. 你可以不要指定開始行和結束行,而是去指定開始行和要跨越的列數。

你可以在我的部落格文章中找到所有的這些屬性的完整細目,我應該嘗試使用 IE 的網格佈局實現方案嗎?

如果你有大量的使用者使用這些瀏覽器,那麼你可能會發現這個老規範是有幫助的。即使你只是用他來解決幾個小問題,那這對你來說也是值得的。

如果要支援這些瀏覽器,我何苦使用網格呢?

如果你的列表中有不支援的瀏覽器,那麼你 必須 為他們提供和那些已經被支援的瀏覽器相同的體驗。然後我們就會懷疑是不是應該用網格佈局,或者任何新的 CSS 特性。使用可行方案,這個方案最完美。

你可能還在考慮使用網格佈局是不是有一個優良的回退方案,如果你知道,短期內很可能你會從“必須是相同的”列表中拋棄一堆不相容的瀏覽器。特別是如果你知道現在做的開發會有很長的維護週期。然後,你可以在晚一點的時候,只使用網格版本,丟掉回退方案。

但是,支援對於你來說意味可能著會失去對一些瀏覽器的相容來換取一些開發工作的簡化,然而此時還非用網格佈局不可,那麼這是使用網格佈局和針對不相容瀏覽器單獨設計非網格佈局體驗的時候。

向後相容性測試

測試向後相容性是最後一步。測試你的回退方案是否奏效的唯一方法就會使用不支援 CSS 網格的瀏覽器訪問你的網站。使用下載微軟提供的虛擬機器的這種方式,你可以不必購買其他電腦。然後,就可以用不支援網格佈局的 Internet Explorer 進行測試。

你可以在手機上下載 UC 瀏覽器,或使用桌面版的 Windows 或者虛擬機器。

還有比如說可以訪問整個執行範圍內瀏覽器的遠端虛擬機器工具 BrowserStack。這些服務不是免費的,但是他們而已為你節省大量設定測試虛擬機器的時間。

BrowserStack 可以訪問到許多不同的瀏覽器和作業系統

BrowserStack可以訪問到許多不同的瀏覽器和作業系統。 (預覽大圖)

我看到有人建議切換特徵查詢值來測試一些不存在的東西。比如測試 display: gridx。這是能正常工作,但是你需要把所有的網格程式碼放到特徵查詢的程式碼塊裡邊,而不是忽略瀏覽器會跳過不支援的 CSS 程式碼的事實。如果你不知道有些網格程式碼可能會結束在特徵查詢之外,那麼你很容易會得到一個虛假的正確結果。即使你在使用這個方法進行快速檢查,我仍然強烈建議你做一些真機測試。

延伸閱讀

我已經列出了這篇文章提到的網址,還有一些額外的資源可以幫助你用自己的方式來支援瀏覽器,同時還能利用到新的佈局方式。如果你遇到了任何好的資源,或者特別棘手的問題,都可以將他們新增到這個問題下面。網格佈局對於我們所有人都是新生的東西,我們可以在生產環境中使用,但是不可避免會出現一些懸而未決的問題,讓我們一起看看。


掘金翻譯計劃 是一個翻譯優質網際網路技術文章的社群,文章來源為 掘金 上的英文分享文章。內容覆蓋 AndroidiOS前端後端區塊鏈產品設計人工智慧等領域,想要檢視更多優質譯文請持續關注 掘金翻譯計劃官方微博知乎專欄

相關文章