深刻探索 CSS Grid

做者:Hammad Ahmed

翻譯:瘋狂的技術宅css

原文:https://scotch.io/tutorials/d...前端

未經容許嚴禁轉載程序員

簡介

本教程將深刻探討 CSS 網格佈局,並探索幾乎全部的屬性和功能。讀完以後,你將可以用這種出色的 CSS 附加功能去處理任何一種佈局。面試

術語:Grid

Grid 是二維網格系統。它能夠用來構建複雜的佈局以及較小的界面。segmentfault

屬性:display

只須要把一個元素的 display 屬性設置爲 grid,它就成了網格。瀏覽器

.grid-to-be {
    display: grid;
}

這樣就使 .grid-to-be 成爲 grid 容器,並使其子項成爲 grid 項目服務器

術語:網格線

在定義明確的網格軌道時會建立網格線。你能夠用它們去放置網格項微信

術語:網格軌道

網格線是兩條網格線之間的空間。網格中的行和列是網格軌道。多線程

屬性:grid-template-columns

可使用 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-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-template

gridgrid-template-rowsgrid-template-columnsgrid-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-rowsgrid-template-columns 建立的網格。隱式網格由 Grid 建立的 網格線網格軌道 組成,用來保存帶有 grid-template-* 屬性的手動建立的網格以外的項目。

自動放置(Auto-placement)

當咱們建立這樣的網格時:

.grid {
    display: grid;
    grid-template-columns: 1fr 1fr 1fr;
}

即便咱們只定義了列,但做爲 .grid 直接子項的單個單元格仍按行放置。這是由於 Grid 包含自動放置規則。

屬性:grid-auto-columns

沒有被 grid-template-columns 所定義的隱式建立的網格列軌道所建立的列的大小,能夠用 grid-template-columns 屬性定義,其默認值爲 auto;你能夠把它設置爲本身所須要的值。

.grid {
    display: grid;
    grid-template-columns: 100px 100px 100px;
    grid-auto-columns: 50px;
}

屬性:grid-auto-rows

grid-auto-rows 的工做方式相似於 grid-template-columns

.grid {
    display: grid;
    grid-template-rows: 100px 100px 100px;
    grid-auto-rows: 50px;
}

屬性:grid-auto-flow

grid-auto-flow 屬性控制 網格單元 如何流入網格,其默認值爲 row

.grid {
    display: grid;
    grid-template-columns: 100px 100px 100px;
    grid-auto-flow: column;
}

上面網格中的「網格單元」將會被一一填充,直到沒有剩餘的項目爲止。

基於行的放置

用行號將項目放置在網格中的操做被稱爲基於行的放置。

屬性:grid-row-start

若是你但願特定的網格項從特定的行開始,則能夠這樣:

.grid-item {
    grid-row-start: 3;
}

屬性:grid-row-end

若是你但願特定的網格項目在特定的行上結束,則能夠這樣:

.grid-item {
    grid-row-end: 6;
}

屬性:grid-column-start

若是你但願特定的網格項目從特定的列開始,能夠這樣:

.grid-item {
    grid-column-start: 3;
}

屬性:grid-column-end

若是你但願特定的網格項在特定的列上結束,能夠這樣:

.grid-item {
    grid-column-end: 6;
}

屬性:grid-row 和 grid-column

能夠用 grid-rowgrid-column 屬性來手動放置和調整網格項目的大小。每一個屬性都是其各自的 star 和 end 屬性的簡寫:grid-row-startgrid-row-endgrid-column-startgrid-column-end

用正斜槓 「/ 」來分隔開始和結束值:

.grid-item {
    grid-column: 3 / 5;
    grid-row: 2 / 7;
}

屬性:grid-area

你能夠把 grid-area 用於對網格行和網格列的簡寫。它是這樣的: / / /
.grid-item {
    grid-area: 2 / 3 / 7 / 5;
}

該代碼的行爲與上一個標題中的代碼相同。

跨網格的元素

要使一個元素跨網格,可使用 grid-rowgrid-column 屬性。設置起始行 1 和結束行 -1。此處 1 表示相關軸上最左邊的網格線,-1 表示相關軸上最右邊的網格線。在從右到左的書寫腳本中,這是相反的,即 1 表示最右邊的行,-1 表示最左邊的行。

.grid-item-weird {
    grid-column: 1 / -1;
}

若是你但願單個項目佔據整個網格,能夠對 grid-rowgrid-column 都這樣作:

.grid-item-weird {
    grid-row: 1 / -1;
    grid-column: 1 / -1;
}

或者簡單地:

.grid-item-weird {
    grid-area: 1 / 1 / -1 / -1;
}

關鍵字:span

當使用 grid-rowgrid-column 時,不用顯式定義行號,而是能夠用 span 關鍵字來聲明該項應涵蓋的行數或列數:

.grid-item {
    grid-column: 3 / span 2;
}

你也能夠把項目固定在終點線上,並朝另外一個方向跨越。下面的代碼實現了與上面相同的結果:

.grid-item {
    grid-column: span 2 / 5;
}

能夠用相同的方式把 span 應用在行上。

術語:網格單元

網格單元格是四個相交的網格線之間的空間,就像表格中的單元格同樣。

術語:網格區域

網格區域是佔據網格上一個矩形區域的網格單元。它們是用命名的網格區域或基於行的放置建立的。

屬性:grid-template-areas (& grid-area)

除了用諸如 spangrid-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-template

gridgrid-template-rowsgrid-template-columnsgrid-template-areas 三個屬性的簡寫。

使用方式以下所示:

.grid {
    grid-template:
        "header    header     header"  80px
        "nav       article    article" 200px
        / 100px auto;
}

能夠像一般那樣定義模板區域,把每行的寬度放在其最右面,而後將全部列的寬度放在正斜槓以後。像之前同樣,你能夠把全部得內容放在同一行。

函數:repeat()

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

這裏的 gridgrid-template-rowsgrid-template-columnsgrid-template-areasgrid-auto-rowsgrid-auto-columnsgrid-auto-flow 六個屬性的簡寫。

首先,你能夠像這樣使用 grid-template(上一個示例):

.grid {
    grid:
        "header    header     header"     80px
        "nav       article    article"    200px
        / 100px auto;
}

其次它不是你看上去的那樣,gridcss 屬性不同:

是的,你沒有看錯:一個名爲 css 的屬性,全部 CSS 屬性的簡寫。我也是在某次思考中偶然知道了它。可是如今我不會教你怎麼用,之後有可能會。

第三,你以某種方式使用 grid。你能夠將 grid-template-rowsgrid-auto-columnsgrid-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

Gutter 是單獨分隔 網格行網格列 的空間。 grid-column-gap, grid-row-gapgrid-gap 是用於定義 gutter 的屬性。

屬性:grid-row-gap

grid-row-gap 用於定義各個 網格行 之間的空間。它是這樣的:

.grid {
    display: grid;
    grid-template-rows: 100px 100px 100px;
    grid-row-gap: 10px;
}

這會將 網格行 彼此隔開10個像素。

屬性:grid-column-gap

grid-column-gap 用於定義各個 網格列 之間的空間。它是這樣的:

.grid {
    display: grid;
    grid-template-columns: 100px 100px 100px;
    grid-column-gap: 10px;
}

這會將 網格列 彼此隔開 10 個像素。

屬性:grid-gap

grid-gap 是將 grid-column-gapgrid-row-gap 結合在一塊兒的簡寫屬性。一個值定義了兩個 gutter。例如:

.grid {
    display: grid;
    grid-template-columns: 100px 100px 100px;
    grid-template-rows: 100px 100px 100px;
    grid-gap: 10px;
}

屬性:order

能夠用 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;
}

上面的例子產生的結果與前面的例子相同。

函數:minmax()

maxmax() 函數是 CSS 網格佈局的新增功能。此功能爲咱們提供了指定 網格軌道 的最小和最大尺寸的方法。

看下面的例子:

.grid {
    display: grid;
    grid-template-columns: 1fr minmax(50px, 100px) 1fr;
}

使用上面的代碼,在減少窗口寬度時,中間列將保持 100px 的寬度,直到第一列和最後一列減少到其內容的寬度爲止。這對於製做響應式佈局特別有用。

關鍵字:auto

若是父容器的尺寸是固定的(例如固定寬度),則 auto 關鍵字做爲網格項目的寬度將會使該項目充滿容器的整個寬度。在有多個項目的狀況下,就像 fr 那樣劃分空間。可是若是將 autofr 一塊兒使用,則 auto 表現爲該項目內容的寬度,剩餘的可用空間被劃分爲 fr

函數:fitcontent()

當你但願寬度或高度表現得像 auto 同樣,但又但願受到最大寬度或高度約束時,能夠用 fitcontent() 函數.

.grid-item {
    width: fitcontent(200px);
}

在這裏,最小爲適合內容,最大爲 200px。

關鍵字:auto-fill

你能夠用 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-fit 的行爲與 auto-fill 相同,不一樣之處在於它會摺疊全部空的重複軌道。空軌道是指沒有放置網格項目或跨越網格項目的軌道。

dense

藉助 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-fillminmax() 之類的關鍵字。


本文首發微信公衆號:前端先鋒

歡迎掃描二維碼關注公衆號,天天都給你推送新鮮的前端技術文章

歡迎掃描二維碼關注公衆號,天天都給你推送新鮮的前端技術文章

歡迎繼續閱讀本專欄其它高贊文章:


相關文章
相關標籤/搜索