做者:Hammad Ahmed翻譯:瘋狂的技術宅css
原文:https://scotch.io/tutorials/d...前端
未經容許嚴禁轉載程序員
本教程將深刻探討 CSS 網格佈局,並探索幾乎全部的屬性和功能。讀完以後,你將可以用這種出色的 CSS 附加功能去處理任何一種佈局。面試
Grid 是二維網格系統。它能夠用來構建複雜的佈局以及較小的界面。segmentfault
只須要把一個元素的 display 屬性設置爲 grid,它就成了網格。瀏覽器
.grid-to-be { display: grid; }
這樣就使 .grid-to-be 成爲 grid 容器,並使其子項成爲 grid 項目。服務器
在定義明確的網格軌道時會建立網格線。你能夠用它們去放置網格項。微信
網格線是兩條網格線之間的空間。網格中的行和列是網格軌道。多線程
可使用 grid-template-columns 屬性來建立列。要定義列,應該按照你但願它們在網格中出現的順序,把grid -template-columns 屬性設置爲列大小。咱們來看一下:框架
.grid { display: grid; grid-template-columns: 100px 100px 100px; }
這裏定義了三個寬度爲 100px 的列。全部網格項將會按順序排列在這些列中。行高將等於該行中最高元素的高度,可是能夠用 grid-template-rows 來進行更改。
請注意,在僅定義列而未定義行的狀況下,元素將會填充列,而後在行中折返。這是因爲 Grid 使用了網格線和網格線建立的隱式網格。
grid-template-rows 用於定義網格中行的數量和大小。它的語法和 grid-template-columns 相似。
.grid { display: grid; grid-template-columns: 100px 100px 100px; grid-template-rows: 100px 100px 100px; }
若是隻有 grid-template-rows 而沒有 grid-template-columns 屬性會致使列寬等於該行中最寬元素的寬度。
grid 是 grid-template-rows、grid-template-columns 和 grid-template-areas 三個屬性的簡寫。
使用方式以下:
.grid { grid-template: "header header header" 80px "nav article article" 600px / 100px 1fr; }
你能夠像平時那樣去定義模板區域,將每行的寬度放在最右面,最後再把全部列的寬度放在正斜槓以後。像之前同樣,你能夠把全部內容放在一行。
fr 是爲 CSS 網格佈局建立的新單位。 fr 使你不須要計算百分比就能建立靈活的網格, 1fr
表示可用空間的一等份。可用空間被分爲等份數字的總數個,因此 3fr 4fr 3fr
把空間劃分爲 3 + 4 + 3 = 10 個部分,分別爲三行或列分配 三、4 和 3 個等份的可用空間。例如:
.grid { display: grid; grid-template-columns: 3fr 4fr 3fr; }
若是將固定單位與彈性單位相混合,則每一個等份的可用空間是在減去固定空間後計算的。讓咱們看另外一個例子:
.grid { display: grid; grid-template-columns: 3fr 200px 3fr; }
單個等份的寬度是這樣計算的:( .grid
的寬度 - 200px) / (3 + 3) 。若是存在間隔(gutter)的話,其空間一開始也會從 .grid
的寬度中減去。這是 fr
和 %
之間的區別,即百分比不包括你用 grid-gap 定義的 gutter。
這裏的 3fr 200px 3fr 基本上等於 1fr 200px 1fr。
顯式網格是使用屬性 grid-template-rows 或 grid-template-columns 建立的網格。隱式網格由 Grid 建立的 網格線 和 網格軌道 組成,用來保存帶有 grid-template-* 屬性的手動建立的網格以外的項目。
當咱們建立這樣的網格時:
.grid { display: grid; grid-template-columns: 1fr 1fr 1fr; }
即便咱們只定義了列,但做爲 .grid 直接子項的單個單元格仍按行放置。這是由於 Grid 包含自動放置規則。
沒有被 grid-template-columns 所定義的隱式建立的網格列軌道所建立的列的大小,能夠用 grid-template-columns 屬性定義,其默認值爲 auto;你能夠把它設置爲本身所須要的值。
.grid { display: grid; grid-template-columns: 100px 100px 100px; grid-auto-columns: 50px; }
grid-auto-rows 的工做方式相似於 grid-template-columns 。
.grid { display: grid; grid-template-rows: 100px 100px 100px; grid-auto-rows: 50px; }
grid-auto-flow 屬性控制 網格單元 如何流入網格,其默認值爲 row。
.grid { display: grid; grid-template-columns: 100px 100px 100px; grid-auto-flow: column; }
上面網格中的「網格單元」將會被一一填充,直到沒有剩餘的項目爲止。
用行號將項目放置在網格中的操做被稱爲基於行的放置。
若是你但願特定的網格項從特定的行開始,則能夠這樣:
.grid-item { grid-row-start: 3; }
若是你但願特定的網格項目在特定的行上結束,則能夠這樣:
.grid-item { grid-row-end: 6; }
若是你但願特定的網格項目從特定的列開始,能夠這樣:
.grid-item { grid-column-start: 3; }
若是你但願特定的網格項在特定的列上結束,能夠這樣:
.grid-item { grid-column-end: 6; }
能夠用 grid-row 和 grid-column 屬性來手動放置和調整網格項目的大小。每一個屬性都是其各自的 star 和 end 屬性的簡寫:grid-row-start,grid-row-end,grid-column-start 和 grid-column-end。
用正斜槓 「/ 」來分隔開始和結束值:
.grid-item { grid-column: 3 / 5; grid-row: 2 / 7; }
你能夠把 grid-area 用於對網格行和網格列的簡寫。它是這樣的:
/ / /
.grid-item { grid-area: 2 / 3 / 7 / 5; }
該代碼的行爲與上一個標題中的代碼相同。
要使一個元素跨網格,可使用 grid-row 或 grid-column 屬性。設置起始行 1 和結束行 -1。此處 1 表示相關軸上最左邊的網格線,-1 表示相關軸上最右邊的網格線。在從右到左的書寫腳本中,這是相反的,即 1 表示最右邊的行,-1 表示最左邊的行。
.grid-item-weird { grid-column: 1 / -1; }
若是你但願單個項目佔據整個網格,能夠對 grid-row 和 grid-column 都這樣作:
.grid-item-weird { grid-row: 1 / -1; grid-column: 1 / -1; }
或者簡單地:
.grid-item-weird { grid-area: 1 / 1 / -1 / -1; }
當使用 grid-row 和 grid-column 時,不用顯式定義行號,而是能夠用 span
關鍵字來聲明該項應涵蓋的行數或列數:
.grid-item { grid-column: 3 / span 2; }
你也能夠把項目固定在終點線上,並朝另外一個方向跨越。下面的代碼實現了與上面相同的結果:
.grid-item { grid-column: span 2 / 5; }
能夠用相同的方式把 span
應用在行上。
網格單元格是四個相交的網格線之間的空間,就像表格中的單元格同樣。
網格區域是佔據網格上一個矩形區域的網格單元。它們是用命名的網格區域或基於行的放置建立的。
除了用諸如 span
、grid-column
之類的東西放置和調整單個網格項目外,還能夠用所謂的「模板區域」。grid-template-area 容許你命名網格區域,以便網格項目能夠進一步填充它們。
.grid { display: grid; grid-template-columns: 100px 1fr 100px; grid-template-rows: 100px 800px 100px; grid-template-areas: "header header header" "sidebar-1 content sidebar-2" "footer footer footer" }
這裏的一對引號表明一行網格。你能夠將全部內容放在一行中,而不用列對齊,可是我所作的只是爲了使它看起來更加整潔。我首先定義了三列三行,而後爲每一個單元命名。經過在第一行中重複執行三次 「header」,告訴 CSS 要作的是用名爲 header 的網格項覆蓋整個過程。其他的也同樣。
如下是經過用 grid-template-areas 命名每一個網格項目,使其擁有爲其定義的空間的方式:
.header { grid-area: header } .sidebar-1 { grid-area: sidebar-1 } .content { grid-area: content } .sidebar-2 { grid-area: sidebar-2 } .footer { grid-area: footer }
沒有什麼比這更容易了,尤爲是用於佈置內容的 CSS 其餘方法。
在前面你已經看到 grid-area
也用於基於行的定位。
若是想把單元格留空,則能夠用點 .
來設置:
.grid { display: grid; grid-template-columns: 100px 1fr 100px; grid-template-rows: 100px 800px 100px; grid-template-areas: "header header header" "sidebar content sidebar" "footer footer ." }
在這裏,頁腳以第二列結束。
grid 是 grid-template-rows,grid-template-columns 和grid-template-areas 三個屬性的簡寫。
使用方式以下所示:
.grid { grid-template: "header header header" 80px "nav article article" 200px / 100px auto; }
能夠像一般那樣定義模板區域,把每行的寬度放在其最右面,而後將全部列的寬度放在正斜槓以後。像之前同樣,你能夠把全部得內容放在同一行。
repeat()
函數有助於使 網格軌道 列表變得不是那麼多餘,併爲其添加了語義層。使用起來很是簡單直觀。咱們來看一下:
你也能夠重複某種形式的軌道列表,以下所示:
.grid { display: grid; grid-template-columns: repeat(3, 1fr 2fr); // this is the same as: 1fr 2fr 1fr 2fr 1fr 2fr }
repeat()
沒必要是值的惟一部分。你能夠在其先後添加其餘的值。例如:grid-template-columns:2fr repeat(5,1fr) 4fr;
。
這裏的 grid 是 grid-template-rows、 grid-template-columns、 grid-template-areas、 grid-auto-rows、 grid-auto-columns 和 grid-auto-flow 六個屬性的簡寫。
首先,你能夠像這樣使用 grid-template(上一個示例):
.grid { grid: "header header header" 80px "nav article article" 200px / 100px auto; }
其次它不是你看上去的那樣,grid 與 css 屬性不同:
是的,你沒有看錯:一個名爲 css 的屬性,全部 CSS 屬性的簡寫。我也是在某次思考中偶然知道了它。可是如今我不會教你怎麼用,之後有可能會。
第三,你以某種方式使用 grid。你能夠將 grid-template-rows 與 grid-auto-columns 或 grid-auto-rows 結合使用。語法很是簡單:
.grid-item { grid: <grid-template-rows> / <grid-auto-columns>; grid: <grid-auto-rows> / <grid-template-columns>; }
例如:
.grid-item-1 { grid: 50px 200px 200px/ auto-flow 60px; } .grid-item-2 { grid: auto-flow 50px / repeat(5, 1fr); }
請注意,在該值以前應該先使用 auto-flow 關鍵字。
Gutter 是單獨分隔 網格行 和 網格列 的空間。 grid-column-gap, grid-row-gap 和 grid-gap 是用於定義 gutter 的屬性。
grid-row-gap 用於定義各個 網格行 之間的空間。它是這樣的:
.grid { display: grid; grid-template-rows: 100px 100px 100px; grid-row-gap: 10px; }
這會將 網格行 彼此隔開10個像素。
grid-column-gap 用於定義各個 網格列 之間的空間。它是這樣的:
.grid { display: grid; grid-template-columns: 100px 100px 100px; grid-column-gap: 10px; }
這會將 網格列 彼此隔開 10 個像素。
grid-gap 是將 grid-column-gap 和 grid-row-gap 結合在一塊兒的簡寫屬性。一個值定義了兩個 gutter。例如:
.grid { display: grid; grid-template-columns: 100px 100px 100px; grid-template-rows: 100px 100px 100px; grid-gap: 10px; }
能夠用 order 屬性來控制網格單元的順序。看下面的例子:
.grid { display: grid; grid-template-columns: 100px 100px 100px; grid-template-rows: 100px 100px 100px; grid-gap: 10px; } .grid .grid-cell:nth-child(5) { order: 1; }
在代碼中,第五個網格單元被放置在網格的最後,由於其餘網格單元根本沒有定義順序。若是定義了順序,則會遵循數字順序。兩個或多個 網格單元 能夠有相同的順序。具備相同順序或徹底沒有順序的文件將會根據 HTML 文檔的邏輯順序進行放置。再看下面:
.grid { display: grid; grid-template-columns: 100px 100px 100px; grid-template-rows: 100px 100px 100px; grid-gap: 10px; } .grid .grid-cell { order: 1 } .grid .grid-cell:nth-child(5) { order: 2; }
上面的例子產生的結果與前面的例子相同。
maxmax() 函數是 CSS 網格佈局的新增功能。此功能爲咱們提供了指定 網格軌道 的最小和最大尺寸的方法。
看下面的例子:
.grid { display: grid; grid-template-columns: 1fr minmax(50px, 100px) 1fr; }
使用上面的代碼,在減少窗口寬度時,中間列將保持 100px 的寬度,直到第一列和最後一列減少到其內容的寬度爲止。這對於製做響應式佈局特別有用。
若是父容器的尺寸是固定的(例如固定寬度),則 auto
關鍵字做爲網格項目的寬度將會使該項目充滿容器的整個寬度。在有多個項目的狀況下,就像 fr
那樣劃分空間。可是若是將 auto
與 fr
一塊兒使用,則 auto 表現爲該項目內容的寬度,剩餘的可用空間被劃分爲 fr
。
當你但願寬度或高度表現得像 auto
同樣,但又但願受到最大寬度或高度約束時,能夠用 fitcontent()
函數.
.grid-item { width: fitcontent(200px); }
在這裏,最小爲適合內容,最大爲 200px。
你能夠用 auto-fill 來用最多的 網格軌道 填充相關的軸(行或列)而不會溢出。要實現這個目的,須要用到 repeat() 函數:
.grid { display: grid; grid-template-columns: repeat(auto-fill, 50px); }
但這會下降單個軌道的靈活性。經過與 minmax() 一塊兒使用,能夠同時具備自動填充功能和靈活性。
.grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(50px, 1fr)); }
這樣,你能夠至少包含一列,而且在特定瀏覽器寬度中包含多個 50px 的列。
請注意,即便可能未用單元格填充, auto-fill 也會建立網格軌道。
auto-fit 的行爲與 auto-fill 相同,不一樣之處在於它會摺疊全部空的重複軌道。空軌道是指沒有放置網格項目或跨越網格項目的軌道。
藉助 dense 關鍵字,你能夠將項目回填到 空網格單元 中,這些單元是由於你嘗試作了一些的奇怪的事(例如spanning)而被建立的。在任何 span 內你均可以將 dense 關鍵字與 grid-auto-flow 配合使用,以下所示:
.grid { display: grid; grid-template-column: repeat(auto-fill, minmax(50px, 1fr)); grid-auto-flow: dense; }
你能夠把它用在照片庫之類的頁面中,但在用於表單時要特別當心,由於這可能會打亂表單子元素的特定順序。
在撰寫本文時,瀏覽器對 CSS 網格佈局有很好的支持。根據 caniuse.com 的說法,除了 Internet Explorer 11部分支持 -ms 前綴和 Opera Mini 以外,全部主流瀏覽器均支持 CSS 網格佈局。
與之前的方法相比,CSS 網格使咱們可以以更高的控制力、便捷性和速度來進行佈局。在本教程中,咱們學習了 Grid 的全部主要元素,包括建立軌道、定位和調整單元格的大小,以及使網格流暢和響應,以及使用諸如 auto-fill
和 minmax()
之類的關鍵字。