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

摘要css

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

在這篇文章中,我將探索現今處理瀏覽器兼容問題的方法。爲了讓咱們如今就用上 CSS 的新特性,咱們能夠作出哪些努力,仍然給那些不支持新特性的瀏覽器提供很好的體驗?android

咱們說的支持是什麼?

在闡明如何在去支持那些自己不支持網格的瀏覽器以前,頗有必要搞明白 支持 的含義。支持也許是站點必須在列表中的瀏覽器上看起來徹底相同。這可能意味着對於全部的瀏覽器,你均可以不用去作一些收尾工做。這可能意味着你在測試這些瀏覽器的時候對他們能得到一致的體驗而感到十分高興。ios

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

若是沒有任何的分析工具,你能夠在 Can I Use 上面導入你所在位置的數據。github

在 Can I Use 上能夠導入你所在位置的使用狀況數據

Can I Use 這個網站上,你能夠導入所在位置的使用狀況數據。 (預覽大圖)web

一樣值得在這裏牢記網站的目標。例如,但願吸引生活在印度等新興市場的訪問者的網站應該確保能在這些國家用戶使用的瀏覽器中正常運行。後端

我僅僅只須要擔憂舊瀏覽器嗎?

截止發稿,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% 的流量,儼然是世界第三大流行的瀏覽器。可是若是碰巧你住在美國或者歐洲,可能你歷來都沒有據說過。

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

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前端後端區塊鏈產品設計人工智能等領域,想要查看更多優質譯文請持續關注 掘金翻譯計劃官方微博知乎專欄

相關文章
相關標籤/搜索