CSS 網格佈局的最佳實踐
已發表: 2022-03-10一個越來越普遍的問題——現在人們在生產中使用 CSS 網格佈局——似乎是“什麼是最佳實踐?” 這個問題的簡短回答是使用規範中定義的佈局方法。 您選擇使用的規範的特定部分,以及您如何將 Grid 與其他佈局方法(例如 Flexbox)結合起來,取決於您嘗試構建的模式以及您和您的團隊希望如何工作。
更深入地看,我認為這種對“最佳實踐”的要求可能表明對使用與以前截然不同的佈局方法缺乏信心。 也許擔心我們將 Grid 用於它不是為它設計的東西,或者在我們應該使用的時候不使用 Grid。 也許歸結為對支持舊瀏覽器的擔憂,或者 Grid 如何融入我們的開發工作流程。
在本文中,我將嘗試介紹一些可以被描述為最佳實踐的事情,以及一些您可能不需要擔心的事情。
該調查
為了幫助了解這篇文章,我想了解其他人是如何在生產中使用網格佈局的,他們面臨的挑戰是什麼,他們真正喜歡什麼? 是否有共同的問題、問題或使用的方法。 為了找出答案,我進行了一項快速調查,詢問人們如何使用網格佈局,特別是他們最喜歡什麼以及他們認為具有挑戰性的問題。
在接下來的文章中,我將引用並直接引用其中一些響應。 我還將鏈接到許多其他資源,您可以在其中找到有關所描述技術的更多信息。 事實證明,在調查回復中,有很多有趣的東西需要解開。 我將在以後的帖子中討論其他一些問題。
可訪問性
如果您在使用時需要注意 Grid 規範的任何部分,那就是在使用任何可能導致內容重新排序的內容時:
“作者必須將 order 和 grid-placement 屬性僅用於視覺上的,而不是邏輯上的內容重新排序。 使用這些功能執行邏輯重新排序的樣式表是不合格的。”
— 網格規範:重新排序和可訪問性
這不是 Grid 獨有的,然而,在二維中如此輕鬆地重新排列內容的能力使得 Grid 面臨更大的問題。 但是,如果使用任何允許內容重新排序的方法——無論是 Grid、Flexbox 還是絕對定位——你需要注意不要將視覺體驗與文檔中的內容結構脫節。 屏幕閱讀器(以及僅使用鍵盤在文檔中導航的人)將遵循源中項目的順序。
需要特別小心的地方是在 Flexbox 中使用flex-direction
反轉順序的時候; Flexbox 或 Grid 中的order
屬性; 使用任何方法放置網格項目,如果它將項目移出文檔中的邏輯順序; 並使用grid-auto-flow
的密集包裝模式。
有關此問題的更多信息,請參閱以下資源:
- 網格佈局和可訪問性 - MDN
- Flexbox 和鍵盤導航斷開連接
我應該使用哪些網格佈局方法?
“在 Grid 中有如此多的選擇,堅持以一致的方式編寫它是一個挑戰(例如,是否命名網格線,定義網格模板區域,後備,媒體查詢)以便它可以由整體維護團隊。”
— 米歇爾·巴克
當您第一次看到 Grid 時,它可能看起來有很多不同的創建佈局的方法。 然而,歸根結底,這一切都歸結為從網格的一條線到另一條線的定位。 您可以根據要實現的佈局以及適合您的團隊和正在構建的站點的佈局進行選擇。
沒有正確或錯誤的方法。 下面,我將介紹一些常見的混淆主題。 在之前的文章“網格陷阱和絆腳石”中,我也已經介紹了許多其他潛在的混淆領域。
我應該使用隱式還是顯式網格?
您使用grid-template-columns
和grid-template-rows
定義的網格稱為顯式網格。 顯式網格允許命名網格上的線,還使您能夠使用-1
定位網格的結束線。 您將選擇一個 Explicit Grid 來做這些事情中的任何一個,並且通常當您設計了一個佈局並且確切地知道您的網格線應該去哪里以及軌道的大小時。
我最常將隱式網格用於行軌道。 我想定義列,但是行將自動調整大小並增長以包含內容。 您可以使用grid-auto-columns
和grid-auto-rows
在某種程度上控制隱式網格,但是,與定義所有內容相比,您的控制權更少。
您需要確定是否確切知道您擁有多少內容以及行數和列數——在這種情況下,您可以創建一個顯式網格。 如果您不知道您有多少內容,而只是想要創建的行或列來容納所有內容,您將使用隱式網格。
不過,可以將兩者結合起來。 在下面的 CSS 中,我在 Explicit Grid 中定義了三列和三行,所以前三行內容如下:
- 高度至少為 200 像素的軌道,但會擴展以使內容更高,
- 固定在 400px 高度的軌道,
- 高度至少為 300 像素的軌道(但會擴展)。
任何進一步的內容都將進入在隱式網格中創建的行中,我正在使用grid-auto-rows
屬性使這些軌道至少 300px 高,擴展為auto
。
.grid { display: grid; grid-template-columns: 1fr 3fr 1fr; grid-template-rows: minmax(200px auto) 400px minmax(300px, auto); grid-auto-rows: minmax(300px, auto); grid-gap: 20px; }
具有靈活列數的靈活網格
通過使用重複符號、自動填充和 minmax,您可以創建一個包含盡可能多的軌道的模式,以適應容器,從而在一定程度上消除對媒體查詢的需要。 這個技術可以在這個視頻教程中找到,也可以在我最近的文章“在 2018 年使用媒體查詢進行響應式設計”中與類似的想法一起演示。
如果您樂於在空間較小時將內容降到較早的內容之下,並且樂於在大小上提供很大的靈活性,請選擇此技術。 您特別要求您的列以最小尺寸顯示,並自動填充。
調查中有一些評論讓我懷疑人們是否在真正想要具有固定列數的網格時選擇了這種方法。 如果您在某些斷點處得到不可預測的列數,您可能會更好地設置列數 - 並根據需要使用媒體查詢重新定義它 - 而不是使用auto-fill
或auto-fit
。
我應該使用哪種軌道尺寸方法?
我在文章“那個盒子有多大?”中詳細描述了軌道尺寸。 了解網格佈局中的大小,”然而,我經常會遇到關於使用哪種軌道大小調整方法的問題。 特別是,有人問我百分比大小和fr
單位之間的區別。
如果您只是按照規定使用fr
單位,那麼它與使用百分比不同,因為它分配了可用空間。 如果您將較大的項目放入軌道中,則fr
until 的工作方式是允許該軌道佔用更多空間並分配剩餘的內容。
.grid { display: grid; grid-template-columns: 1fr 1fr 1fr; grid-gap: 20px; }
要使fr
單元分配網格容器中的所有空間,您需要使用minmax()
為其指定最小大小為0
。
.grid { display: grid; grid-template-columns: minmax(0,1fr) minmax(0,1fr) minmax(0,1fr); grid-gap: 20px; }
因此,您可以選擇在以下任一場景中使用fr
:您確實希望根據 auto 進行空間分配(默認行為),以及您希望平均分配的場景。 我通常會使用fr
單元,因為它會為您計算尺寸,並允許使用固定寬度的軌道或間隙。 我唯一使用百分比的時候是當我將網格組件添加到也使用其他佈局方法的現有佈局中時。 如果我希望我的網格組件與使用百分比的基於浮動或 flex 的佈局對齊,那麼在我的網格佈局中使用它們意味著所有內容都使用相同的大小調整方法。
自動放置物品或設置它們的位置?
您經常會發現您只需要在佈局中放置一兩個項目,其餘的根據內容順序就位。 事實上,這是一個非常好的測試,你沒有斷開源和視覺顯示。 如果事情幾乎基於自動放置就位,那麼它們可能處於良好狀態。
然而,一旦我決定了所有事情的去向,我確實傾向於為所有事情分配一個位置。 這意味著如果有人在文檔中添加了一些東西並且網格會自動將其放置在一個意想不到的地方,我不會最終發生奇怪的事情,從而丟棄佈局。 如果所有內容都已放置,Grid 會將該項目放入下一個可用的空網格單元格中。 這可能不是您想要的位置,但在佈局的最後坐下可能比跳到中間並推動其他東西要好。
使用哪種定位方法?
使用網格佈局時,最終一切都歸結為將項目從一行放置到另一行。 其他一切本質上都是幫助者。
與您的團隊一起決定是否要命名線條、使用網格模板區域,或者是否要使用不同類型佈局的組合。 我發現我特別喜歡將網格模板區域用於小型組件。 然而,沒有對錯之分。 找出最適合您的方法。
網格與其他佈局機制相結合
請記住,網格佈局並不是一個真正的佈局方法來統治它們,它是為某種類型的佈局而設計的——即二維佈局。 其他佈局方法仍然存在,您應該考慮每種模式以及最適合的模式。
我認為這對於我們這些習慣於使用佈局方法來讓他們做一些他們不是真正為之設計的事情的人來說實際上是相當困難的。 現在是退後一步的好時機,看看它們設計任務的佈局方法,並記住將它們用於這些任務。
特別是,無論我多久寫一次關於 Grid 與 Flexbox 的文章,都會有人問我應該使用哪一個。 有許多模式,其中任何一種佈局方法都非常有意義,這完全取決於您。 沒有人會因為您選擇 Flexbox over Grid 或 Grid over Flexbox 而大喊大叫。
在我自己的工作中,我傾向於將 Flexbox 用於我希望項目的自然大小來強烈控制其佈局的組件,本質上是推動其他項目。 我也經常使用 Flexbox,因為我想要對齊,因為 Box Alignment 屬性只能在 Flexbox 和 Grid 中使用。 我可能有一個帶有一個子項的 Flex 容器,以便我可以對齊該子項。
Flexbox 可能不是我應該選擇的佈局方法的一個跡像是,當我開始為 flex 項目添加百分比寬度並將flex-grow
設置為 0 時。為 flex 項目添加百分比寬度的原因通常是因為我試圖行它們在二維中排列(在二維中排列正是 Grid 的用途)。 但是,兩者都試一下,看看哪一個似乎最適合內容或設計模式。 這樣做不太可能導致任何問題。
嵌套網格和彈性項目
這也經常出現,將 Grid Item 設為 Grid Container 絕對沒有問題,從而將一個網格嵌套在另一個網格中。 你可以對 Flexbox 做同樣的事情,製作一個 Flex Item 和 Flex Container。 您還可以將 Grid Item 和 Flex Container 或 Flex Item 設為 Grid Container — 這些都不是問題!
我們目前不能做的是將一個網格嵌套在另一個網格中,並讓嵌套網格使用在整個父級上定義的網格軌道。 這將非常有用,也是網格規範第 2 級中的子網格提案希望解決的問題。 嵌套網格當前成為新網格,因此您需要小心調整大小以確保它與任何父軌道對齊。
一頁上可以有多個網格
調查中出現了幾次讓我感到驚訝的評論,似乎有一種想法,即網格應該僅限於主佈局,並且一頁上的許多網格可能不是一件好事。 您可以擁有任意數量的網格! 對大事和小事使用網格,如果將其佈置為網格有意義,則使用網格。
回退和支持舊瀏覽器
“與@supports 結合使用的網格使我們能夠更好地控制我們可以預期看到的佈局變化的數量。 它還與我們的漸進增強方法配合得非常好,這意味著我們可以獎勵那些使用現代瀏覽器的人,而不會阻止那些不使用最新技術的人訪問內容。”
——喬·蘭伯特(Joe Lambert)在rareloop.com 上工作
在調查中,許多人提到了舊版瀏覽器,但是,由於功能查詢和 Grid 覆蓋其他佈局方法的事實,認為支持舊版瀏覽器很難的人和認為支持舊瀏覽器容易的人之間存在相當大的差距。 我在“使用 CSS 網格:支持沒有網格的瀏覽器”中詳細介紹了創建這些後備的機制。
一般來說,現代瀏覽器比早期的瀏覽器更具有互操作性。 我們往往會看到更少的實際“瀏覽器錯誤”,如果您正確使用 HTML 和 CSS,那麼您通常會發現您在一個瀏覽器中看到的內容與在另一個瀏覽器中看到的內容相同。
當然,我們確實有這樣的情況,其中一個瀏覽器還沒有提供對某個規範或某個規範的某些部分的支持。 使用 Grid,我們非常幸運,因為瀏覽器在很短的時間內以非常完整且可互操作的方式提供了 Grid Layout。 因此,我們對測試的考慮往往是需要測試有 Grid 和沒有 Grid 的瀏覽器。 您可能還選擇在 IE10 和 IE11 中使用-ms
前綴版本,這需要作為第三種類型的瀏覽器進行測試。
支持現代網格佈局(不是 IE 版本)的瀏覽器也支持特徵查詢。 這意味著您可以在使用之前測試網格支持。
測試不支持網格的瀏覽器
當為不支持網格佈局的瀏覽器使用回退(或為 IE10 和 11 使用-ms
前綴版本)時,您將需要測試這些瀏覽器如何呈現網格佈局。 為此,您需要一種在示例瀏覽器中查看站點的方法。
我不會通過檢查是否支持無意義的東西或拼寫錯誤的值來破壞您的功能查詢的方法grid
。 這種方法只有在您的樣式表非常簡單並且您已經將與網格佈局有關的所有內容都放在功能查詢中時才有效。 這是一種非常脆弱且耗時的工作方式,尤其是在您廣泛使用 Grid 的情況下。 此外,舊版瀏覽器不僅不支持網格佈局,還會不支持其他 CSS 屬性。 如果您正在尋找“最佳實踐”,那麼設置自己,以便您能夠很好地測試您的工作,那就是高高在上!
有幾種簡單的方法可以讓你自己設置一個合適的方法來測試你的後備。 最簡單的方法——如果你有相當快的互聯網連接並且不介意支付訂閱費——是使用諸如 BrowserStack 之類的服務。 這是一項服務,可讓您在整個主機上的真實瀏覽器上查看網站(甚至是您計算機上正在開發的網站)。 BrowserStack 確實為開源項目提供免費帳戶。
要在本地進行測試,我的建議是使用安裝了目標瀏覽器的虛擬機。 Microsoft 提供免費的虛擬機下載,其中 IE 版本回到 IE8 和 Edge。 您還可以在 VM 上安裝完全不支持 Grid 的舊版瀏覽器。 例如,通過獲取 Firefox 51 或更低版本的副本。 安裝舊版 Firefox 後,請務必按照此處的說明關閉自動更新,否則它會自動更新!
然後,您可以在一個 VM 上在 IE11 和不支持的 Firefox 中測試您的站點(這是一個比拼寫錯誤值更脆弱的解決方案)。 設置可能需要你一個小時左右,但你將在一個非常好的地方測試你的後備。
忘掉舊習慣
“這是我第一次使用網格佈局,所以有很多概念要學習,屬性要理解。 從概念上講,我發現最難忘記我多年來所做的所有事情,比如清理浮動和將所有東西打包到容器 div 中。”
— 隱藏在 hiddedevries.nl/en 上的工作
許多對調查做出回應的人提到需要摒棄舊習慣,以及對於完全不熟悉 CSS 的人來說學習 Layout 會變得更容易。 我傾向於同意。 面對面教學時,初學者使用 Grid 幾乎沒有問題,而有經驗的開發人員則努力將網格恢復為一維佈局方法。 我已經看到使用 CSS Grid 的“網格系統”嘗試添加回基於浮動或基於 flex 的網格所需的行包裝器。
不要害怕嘗試新技術。 如果您有能力在幾個瀏覽器中進行測試並註意潛在的可訪問性問題,那麼您真的不會錯得太遠。 而且,如果您找到了創建特定模式的好方法,請讓其他人知道它。 我們都是在生產中使用 Grid 的新手,所以肯定有很多東西可以發現和分享。
“網格佈局是自媒體查詢以來最令人興奮的 CSS 開發。 它經過深思熟慮,可以滿足實際開發人員的需求,並且在生產中使用絕對是一種樂趣——對於設計師和開發人員來說都是如此。”
— Trys Mudford 在 trysmudford.com 上工作
總結一下,這是一個非常簡短的當前最佳實踐列表! 如果您發現在您自己的情況下效果很好或效果不佳的事情,請將它們添加到評論中。
- 非常注意內容重新排序的可能性。 檢查您是否沒有斷開視覺顯示與文檔訂單的連接。
- 使用帶有本地或遠程虛擬機的真實目標瀏覽器進行測試。
- 不要忘記舊的佈局方法仍然有效且有用。 嘗試不同的方法來實現模式。 不要因為不得不使用 Grid 而掛斷電話。
- 要知道,作為一名經驗豐富的前端開發人員,您可能對佈局的工作原理有一整套先入之見。 嘗試重新審視這些新方法,而不是強迫它們回到舊模式。
- 繼續嘗試。 我們都是新手。 測試您的工作並分享您的發現。