CSS Grid Layout,旨在徹底改變咱們處理網格的方式,它是二維表格系統。CSS 常常被用來佈局,即便它表現得不是很出色。起初,咱們使用tabels、floats、position 和 inline-block,但全部這些方法基本上都是黑科技,並會遺漏許多重要功能(例如垂直居中)。Flexbox 在這方便幫了忙,但它的目標是簡單的一維佈局,而不是複雜的二維佈局。(事實上,Flexbox 和 Grid 能很好地協做。)Grid 是第一個設計出來用於佈局的 CSS 模塊。css
開始你要用 display: grid
定義一個表格容器,用 grid-template-columes
和 grid-template-rows
設置列和行的尺寸,而後將子元素放在表格的列和行中。跟 Flexbox
類似,網格項的順序可有可無。您的 CSS 能夠將它們任意排序,使用媒體查詢來重排佈局也很是容易。想象一下,定義整個頁面的佈局,而後只需幾行 CSS 就能徹底從新排列它來適應不一樣的屏幕寬度,Grid 是有史以來最強大的 CSS 模塊之一。html
截至2017年3月,大多數瀏覽器都提供原生的,沒有前綴的 CSS Grid 支持:Chrome(包括Android),Firefox,Safari(包括iOS)和Opera。另外一方面,Internet Explorer 10 和11支持它,但它是一種過期語法。如今是用 Grid 構建的時候了!git
Chrome | Opera | Firefox | IE | Edge | Safari |
---|---|---|---|---|---|
57 | 44 | 52 | 11* | 16 | 10.1 |
iOS Safari | Opera Mobile | Opera Mini | Android | Android Chrome | Android Firefox |
---|---|---|---|---|---|
10.3 | 46 | No | 67 | 74 | 67 |
在深刻研究 Grid 以前,理解術語很是重要。因爲這裏涉及的術語在概念上都類似,若是你不首先記住網格規範定義的含義,很容易將它們彼此混淆。但別擔憂,它們並很少。github
應用 display: grid
的元素,它是表格項的直接父元素。在下面例子中, container 就是網格容器。算法
<div class="container">
<div class="item item-1"></div>
<div class="item item-2"></div>
<div class="item item-3"></div>
</div>
複製代碼
它是網格容器的直接子元素,下面例子中 item 就是網格項,但 sub-item 不是。瀏覽器
<div class="container">
<div class="item"></div>
<div class="item">
<p class="sub-item"></p>
</div>
<div class="item"></div>
</div>
複製代碼
網格結構的分割線。有垂直(網格列線)、水平(網格行線)、駐留在行和列兩側的線。下面黃色的就是網格列線。ide
兩個相鄰網格線之間的空間。你能把它們想象成是網格列或行。下面的網格軌道就是第二條和第三條行線之間的空間。svg
兩個相鄰行和兩個相鄰列網格線之間的空間。它是網格的單個「單元」。這是行網格線1和2以及列網格線2和3之間的網格單元。函數
四個網格線包圍的總空間。網格區域能夠包括任意數量的網格單元。這是行網格線1和3以及列網格線1和3之間的網格區域。佈局
將元素定義爲網格容器,併爲其內容創建新的網格格式上下文。
值:
grid - 產生塊級網格
inline-grid - 產生內聯級網格
.container {
display: grid | inline-grid;
}
複製代碼
使用以空格分隔的值列表定義網格的列和行。值表示軌道大小,它們之間的空間表示網格線。
值:
<track-size>
- 能夠是一段長度、百分比、或者表格空間中的一部分(使用 fr
單位)
<line-name>
- 您選擇的任意名稱
.container {
grid-template-columns: <track-size> ... | <line-name> <track-size> ...;
grid-template-rows: <track-size> ... | <line-name> <track-size> ...;
}
複製代碼
舉例,當您在軌道值之間留出空白區域時,網格線會自動分配正數和負數:
.container {
grid-template-columns: 40px 50px auto 50px 40px;
grid-template-rows: 25% 100px auto;
}
複製代碼
但您能夠選擇明確命名行。請注意行名稱的括號語法:
.container {
grid-template-columns: [first] 40px [line2] 50px [line3] auto [col4-start] 50px [five] 40px [end];
grid-template-rows: [row1-start] 25% [row1-end] 100px [third-line] auto [last-line];
}
複製代碼
請注意,一行能夠有多個名稱。例如,這裏第二行將有兩個名稱:row1-end
和 row2-start
:
.container {
grid-template-rows: [row1-start] 25% [row1-end row2-start] 25% [row2-end];
}
複製代碼
若是您的定義包含重複部分,你可使用 repeat()
方法來簡化:
.container {
grid-template-columns: repeat(3, 20px [col-start]);
}
複製代碼
上面代碼等價於:
.container {
grid-template-columns: 20px [col-start] 20px [col-start] 20px [col-start];
}
複製代碼
若是多行共享相同的名稱,則能夠經過其行名稱和計數來引用它們。
.item {
grid-column-start: col-start 2;
}
複製代碼
fr
單元容許您將軌道的大小設置爲網格容器的可用空間的一部分。例如,這會將每一個項目設置爲網格容器寬度的三分之一:
.container {
grid-template-columns: 1fr 1fr 1fr;
}
複製代碼
在任何非靈活項目以後計算可用空間。在此示例中,fr
單元可用的總可用空間量不包括50px:
.container {
grid-template-columns: 1fr 50px 1fr 1fr;
}
複製代碼
經過引用使用
grid-area
屬性指定的網格區域的名稱來定義網格模板。重複網格區域的名稱會致使內容跨越這些單元格。句點表示空單元格。語法自己提供了網格結構的可視化。
值:
<grid-area-name>
- 用 grid-area
制定的網格區域名稱
.
- 句點表示空白網格區域
none
- 沒有定義網格區域
.container {
grid-template-areas:
"<grid-area-name> | . | none | ..."
"...";
}
複製代碼
舉例:
.item-a {
grid-area: header;
}
.item-b {
grid-area: main;
}
.item-c {
grid-area: sidebar;
}
.item-d {
grid-area: footer;
}
.container {
display: grid;
grid-template-columns: 50px 50px 50px 50px;
grid-template-rows: auto;
grid-template-areas:
"header header header header"
"main main . sidebar"
"footer footer footer footer";
}
複製代碼
這將建立一個四列寬三行高的網格。整個頂行將由標題區域組成。中間行將包括兩個主要區域,一個空單元格和一個側邊欄區域。最後一行是全部頁腳。
聲明中的每一行都須要具備相同數量的單元格。
您可使用任意數量的相鄰句點來聲明單個空單元格。只要它們之間沒有空格,它們就表明一個單元格。
請注意,您沒有使用此語法命名行,而只是命名了區域。使用此語法時,區域兩端的線條實際上會自動命名。若是網格區域的名稱爲 foo
,則區域的起始行和起始列行的名稱將爲 foo-start
,其最後一行和最後一行的名稱將爲 foo-end
。這意味着某些行可能有多個名稱,例如上例中的最左邊的行,它將有三個名稱:header-start
,main-start
和 footer-start
。
在單個聲明中設置
grid-template-rows
,grid-template-columns
和grid-template-areas
的簡寫。
值:
none
- 設置3個屬性爲它們的初始值
<grid-template-rows> / <grid-template-columns>
- 設置 grid-template-columns
和 grid-template-rows
爲特定值,設置 grid-template-areas
爲 none
.container {
grid-template: none | <grid-template-rows> / <grid-template-columns>;
}
複製代碼
它也能接受一個複雜且包含三者的語法,下面是個例子:
.container {
grid-template:
[row1-start] "header header header" 25px [row1-end]
[row2-start] "footer footer footer" 25px [row2-end]
/ auto 50px auto;
}
複製代碼
等價於:
.container {
grid-template-rows: [row1-start] 25px [row1-end row2-start] 25px [row2-end];
grid-template-columns: auto 50px auto;
grid-template-areas:
"header header header"
"footer footer footer";
}
複製代碼
因爲 grid-template
沒有重置隱式網格屬性(grid-auto-columns
,grid-auto-rows
和 grid-auto-flow
),這多是你想要在大多數狀況下作的,因此建議使用網格屬性而不是網格模板。
指定網格線的大小。您能夠將其視爲設置列/行之間的裝訂線寬度。
值:
<line-size>
- 一個長度值
.container {
grid-column-gap: <line-size>;
grid-row-gap: <line-size>;
}
複製代碼
舉例:
.container {
grid-template-columns: 100px 50px 100px;
grid-template-rows: 80px auto 80px;
grid-column-gap: 10px;
grid-row-gap: 15px;
}
複製代碼
間距只能在行和列之間產生,外邊沒法設置間距。
注意:grid-column-gap
和 grid-row-gap
的 前綴 grid-
被移除,並被從新命名成 column-gap
和 row-gap
。 無前綴屬性已經獲得 Chrome 68+、Safari 11.二、Opera 54+ 的支持。
grid-row-gap
和grid-column-gap
的簡寫
值:
<grid-row-gap> <grid-column-gap>
- 長度值
.container {
grid-gap: <grid-row-gap> <grid-column-gap>;
}
複製代碼
舉個例子:
.container {
grid-template-columns: 100px 50px 100px;
grid-template-rows: 80px auto 80px;
grid-gap: 15px 10px;
}
複製代碼
若是沒有 grid-row-gap
被定義,它將被設置成跟 grid-column-gap
同樣的值。
注意: grid-gap
的前綴也被移除了,被從新命名成 gap
。也獲得了 Chrome 68+ 、 Safari 11.2+ 和 Opera 54+ 的支持。
沿着內聯(行)軸對齊網格項(而不是沿着塊(列)軸對齊的對齊項)。此值適用於容器內的全部網格項。
值:
strat
- 與單元格的起始邊緣對奇
end
- 與單元格的結束邊緣對齊
center
- 與單元的中心對齊
stretch
- 拉伸使其充滿整個單元格(默認值)
.container {
justify-items: start | end | center | stretch;
}
複製代碼
舉例:
.container {
justify-items: start;
}
複製代碼
.container {
justify-items: end;
}
複製代碼
.container {
justify-items: center;
}
複製代碼
.container {
justify-items: stretch;
}
複製代碼
這些行爲也能經過網格項的 justify-self
來從新定義。
沿着列網格線對齊網格項(而不是沿着行網格線對齊的對齊項)。此值適用於容器內的全部網格項。
值:
start
- 將其與單元格上邊緣對齊
end
- 將其與單元格下邊緣對齊
center
- 將其與單元格中間對齊
stretch
- 豎向延伸到整個單元格
.container {
align-items: start | end | center | stretch;
}
複製代碼
舉例:
.container {
align-items: start;
}
複製代碼
.container {
align-items: end;
}
複製代碼
.container {
align-items: center;
}
複製代碼
.container {
align-items: stretch;
}
複製代碼
這個表現也可以經過 align-self
去單獨設置網格單元。
place-items
一個聲明可以同時設置align-items
和justify-items
兩個屬性
值:
<align-items> / <justify-items>
- 第一個值設置 align-items
,第二個值設置 justify-items
。若是沒有第二個值,則兩個屬性的值同樣。除 Edge
以外的全部主流瀏覽器都支持 place-items
屬性。
有時您的內容區域可能會小於整個網格區域。若是您的全部網格項都使用非靈活單位(如
px
)進行大小調整,則可能會發生這種狀況。在這種狀況下,您能夠在網格容器中設置網格的對齊方式。此屬性沿着內聯(行)軸對齊網格(而不是沿着塊(列)軸對齊網格的對齊內容)。
值: start
- 將網格與網格容器的起始邊緣齊平
end
- 將網格與網格容器的結束邊緣齊平
center
- 將網格與網格容器的中間齊平
stretch
- 調整網格項的大小以容許網格填充網格容器的整個寬度
space-around
- 在每一個網格項之間放置一個均勻的空間,在遠端放置半個大小的空格
space-between
- 在每一個網格項之間放置一個偶數空間,在遠端沒有空格
space-evenly
- 在每一個網格項之間放置一個均勻的空間,包括遠端
.container {
justify-content: start | end | center | stretch | space-around | space-between | space-evenly;
}
複製代碼
舉例:
.container {
justify-content: start;
}
複製代碼
.container {
justify-content: end;
}
複製代碼
.container {
justify-content: center;
}
複製代碼
.container {
justify-content: stretch;
}
複製代碼
.container {
justify-content: space-around;
}
複製代碼
.container {
justify-content: space-between;
}
複製代碼
.container {
justify-content: space-evenly;
}
複製代碼
有時網格總尺寸會比網格容器小。在網格項用非彈性單位(例如
px
)設置尺寸時會發生這種現象。這種狀況下你可以設置網格的對準方式。這個屬性是設置列軸的對齊方式,上面所講的justify-content
則是設置行軸方向的!
值:
start
- 將網格對齊在網格容器的上起始邊緣線
end
- 將網格對齊在網格容器的下邊緣線
center
- 將網格對齊在網格容器的中心
stretch
- 講網格拉伸充滿整個網格容器
space-around
- 在每一個行網格項之間放置一個均勻的空間,在兩端放置半個大小的空格
space-between
- 在每一個行網格項之間放置一個均勻的空間,兩端沒有空格
space-evenly
- 在每一個行網格項之間和兩端放置一個均勻的空間
.container {
align-content: start | end | center | stretch | space-around | space-between | space-evenly;
}
複製代碼
舉例:
.container {
align-content: start;
}
複製代碼
.container {
align-content: end;
}
複製代碼
.container {
align-content: center;
}
複製代碼
.container {
align-content: stretch;
}
複製代碼
.container {
align-content: space-around;
}
複製代碼
.container {
align-content: space-between;
}
複製代碼
.container {
align-content: space-evenly;
}
複製代碼
place-content
是同時設置justify-content
和align-content
的簡寫形式
值:
<align-content>/<justify-content>
- 第一個值設置 align-conent
,第二個值設置 justify-content
。若是第二個值被忽略,那麼第一個值就對兩個屬性生效。
指定任何自動生成的網格軌道的大小(也稱爲隱式網格軌道)。當網格項目多於網格中的單元格或網格項目放置在顯式網格以外時,將建立隱式軌道。
值: <track-size>
- 能夠是一個長度、百分比、或者是 fr
單位。
.container {
grid-auto-columns: <track-size> ...;
grid-auto-rows: <track-size> ...;
}
複製代碼
爲了說明如何建立隱式網格軌道,請考慮如下事項:
.container {
grid-template-columns: 60px 60px;
grid-template-rows: 90px 90px
}
複製代碼
上述代碼建立了 2*2 的網格。
.item-a {
grid-column: 1 / 2;
grid-row: 2 / 3;
}
.item-b {
grid-column: 5 / 6;
grid-row: 2 / 3;
}
複製代碼
咱們設置 .item-b 的寬度在第五列和第六列之間,可是咱們沒有定義這兩列。由於咱們引用了不存在的行,因此建立寬度爲0的隱式軌道以填充間隙。咱們可使用 grid-auto-columns
和 grid-auto-rows
來指定這些隱式軌道的寬度:
.container {
grid-auto-columns: 60px;
}
複製代碼
若是您沒有明確放置在網格上的網格項,則自動放置算法會自動放置項目。此屬性控制自動放置算法的工做方式。
值:
row
- 告訴自動放置算法依次填充每一行,根據須要添加新行(默認值)
column
- 告訴自動放置算法依次填寫每一個列,根據須要添加新列
dense
- 告訴自動放置算法,若是稍後出現較小的項目,則嘗試填充網格中較早的空閒位置
.container {
grid-auto-flow: row | column | row dense | column dense
}
複製代碼
注意,dense 只會更改項目的可視順序,並可能致使它們出現亂序,這不利於可訪問性。
例子:
<section class="container">
<div class="item-a">item-a</div>
<div class="item-b">item-b</div>
<div class="item-c">item-c</div>
<div class="item-d">item-d</div>
<div class="item-e">item-e</div>
</section>
複製代碼
經過下面的 css 將網格設置成5列2行,設置 grid-auto-flow
值爲 row
(該屬性的默認值):
.container {
display: grid;
grid-template-columns: 60px 60px 60px 60px 60px;
grid-template-rows: 30px 30px;
grid-auto-flow: row;
}
複製代碼
而後咱們在網格項中放置項目:
.item-a {
grid-column: 1;
grid-row: 1 / 3;
}
.item-e {
grid-column: 5;
grid-row: 1 / 3;
}
複製代碼
咱們設置了 grid-auto-flow: row;
咱們的網格以下圖所示。請注意咱們沒有放置的3項(item-b,item-c,item-d):
若是咱們將 grid-auto-flow 設置成 column ,效果以下:
.container {
display: grid;
grid-template-columns: 60px 60px 60px 60px 60px;
grid-template-rows: 30px 30px;
grid-auto-flow: column;
}
複製代碼
設置如下屬性的簡寫形式(包括
grid-template-rows
、grid-template-columns
、grid-auto-rows
、grid-auto-columns
和grid-auto-flow
)(注意:您只能在單個網格聲明中指定顯式或隱式網格屬性)
值:
none
- 將全部子屬性設置爲初始值
<grid-template>
- 跟 grid-template
同樣
<grid-template-rows>/[auto-flow && dense?]<grid-auto-columns>?
- 將 grid-template-rows
設置爲指定的值。若是 auto-flow
關鍵字位於斜槓的右側,則會將 grid-auto-flow
設置爲 column
。若是另外指定了密集關鍵字,則自動放置算法使用「密集」打包算法。若是省略 grid-auto-columns
,則將其設置爲 auto
。
[ auto-flow && dense? ]<grid-auto-rows>?/<grid-template-columns>
- 將 grid-template-columns
設置爲指定的值。若是 auto-flow
關鍵字位於斜槓的左側,則會將 grid-auto-flow
設置爲 row
。若是另外指定了 dense
關鍵字,則自動放置算法使用 「dense
」 打包算法。若是省略 grid-auto-rows
,則將其設置爲 auto
。
例子:
下面兩個代碼塊是等價的:
.container {
grid: 100px 300px / 3fr 1fr;
}
複製代碼
.container {
grid-template-rows: 100px 300px;
grid-template-columns: 3fr 1fr;
}
複製代碼
下面兩個代碼塊也是等價的:
.container {
grid: auto-flow / 200px 1fr;
}
複製代碼
.container {
grid-auto-flow: row;
grid-template-columns: 200px 1fr;
}
複製代碼
下面兩個代碼塊也是等價的:
.container {
grid: auto-flow dense 100px / 1fr 2fr;
}
複製代碼
.container {
grid-auto-flow: row dense;
grid-auto-rows: 100px;
grid-template-columns: 1fr 2fr;
}
複製代碼
下面兩個代碼塊也是等價的:
.container {
grid: 100px 300px / auto-flow 200px;
}
複製代碼
.container {
grid-template-rows: 100px 300px;
grid-auto-flow: column;
grid-auto-columns: 200px;
}
複製代碼
它還接受一個更復雜但很是方便的語法來一次設置全部內容。您能夠指定 grid-template-areas
,grid-template-rows
和 grid-template-columns
,並將全部其餘子屬性設置爲其初始值。您正在作的是指定行名稱和軌道大小與其各自的網格區域內聯。用一個例子來幫助理解:
.container {
grid: [row1-start] "header header header" 1fr [row1-end]
[row2-start] "footer footer footer" 25px [row2-end]
/ auto 50px auto;
}
複製代碼
上面代碼等價於:
.container {
grid-template-areas:
"header header header"
"footer footer footer";
grid-template-rows: [row1-start] 1fr [row1-end row2-start] 25px [row2-end];
grid-template-columns: auto 50px auto;
}
複製代碼
注意:
float
、display: inline-block
、display: table-cell
、vertical-align
和column-*
屬性對網格沒有影響。
經過網格線來決定網格項在網格容器中的位置。顧名思義,
grid-column-start
/grid-row-start
決定了網格項的起始邊緣,grid-column-end
/grid-row-end
決定了網格項的結束邊緣。
值:
line
- 能夠是指定網格線的數字或者其餘命名
span<number>
- 該項目將跨越提供的網格軌道數量
span<name>
- 該項目將跨越,直到它使用提供的名稱命中下一行
auto
- 自動放置,自動和默認跨度都默認是1
.item {
grid-column-start: <number> | <name> | span <number> | span <name> | auto;
grid-column-end: <number> | <name> | span <number> | span <name> | auto;
grid-row-start: <number> | <name> | span <number> | span <name> | auto;
grid-row-end: <number> | <name> | span <number> | span <name> | auto;
}
複製代碼
舉例:
.item-a {
grid-column-start: 2;
grid-column-end: five;
grid-row-start: row1-start
grid-row-end: 3;
}
複製代碼
.item-b {
grid-column-start: 1;
grid-column-end: span col4-start;
grid-row-start: 2
grid-row-end: span 2
}
複製代碼
若是沒有聲明 grid-column-end
/ grid-row-end
,網格項默認跨越一個軌道。
網格項會堆疊,可使用 z-index
控制堆疊順序。
grid-column-start
+grid-column-end
和grid-row-start
+grid-row-end
的簡寫。
值:
<start-line>/<end-line>
- 每一個屬性接收跟單個一樣的值,包括span
.item {
grid-column: <start-line> / <end-line> | <start-line> / span <value>;
grid-row: <start-line> / <end-line> | <start-line> / span <value>;
}
複製代碼
舉例:
.item-c {
grid-column: 3 / span 2;
grid-row: third-line / 4;
}
複製代碼
沒有聲明結束線時,網格項默認跨越一個軌道。
爲網格項指定名稱,以即可以使用
grid-template-areas
屬性建立的模板引用該項目。或者,此屬性可用做網格行開始 + 網格列開始 + 網格行結束 + 網格列結束的更短的簡寫。
值:
<name>
- 一個名稱
<row-start>/<column-start>/<row-end>/<column-end>
- 能夠是數字或命名行
.item {
grid-area: <name> | <row-start> / <column-start> / <row-end> / <column-end>;
}
複製代碼
舉例:
下面給網格項設置一個名稱:
.item-d {
grid-area: header;
}
複製代碼
做爲 grid-row-start
+ grid-column-start
+ grid-row-end
+ grid-column-end
的簡寫:
.item-d {
grid-area: 1 / col4-start / last-line / 6;
}
複製代碼
沿着行軸對齊單元格內的網格項,此值適用於單個單元格內的網格項。
值:
start
- 將網格項對齊以與單元格的起始邊緣齊平
end
- 將網格項對齊以與單元格的結束邊緣齊平
center
- 對齊單元格中心的網格項
stretch
- 填充整個單元格的寬度
.item {
justify-self: start | end | center | stretch;
}
複製代碼
舉例:
.item-a {
justify-self: start;
}
複製代碼
.item-a {
justify-self: end;
}
複製代碼
.item-a {
justify-self: center;
}
複製代碼
.item-a {
justify-self: stretch;
}
複製代碼
若是要設置全部網格項的行軸對齊方式,能夠經過網格容器屬性 justify-items
。
沿着列軸對齊單元格內的網格項,此值適用於單個網格項內的內容。
值:
start
- 將網格項與單元格的上邊緣齊平
end
- 將網格項與單元格的下邊緣齊平
center
- 將網格項與單元格的中心對齊
stretch
- 填充整個單元格的高度
.item {
align-self: start | end | center | stretch;
}
複製代碼
舉例:
.item-a {
align-self: start;
}
複製代碼
.item-a {
align-self: end;
}
複製代碼
.item-a {
align-self: center;
}
複製代碼
.item-a {
align-self: stretch;
}
複製代碼
若是要設置網格容器全部項的列軸對齊方式,能夠經過屬性 align-items
去設置。
同時設置
align-self
和justify-self
兩個屬性的簡寫形式。
值:
auto
- 佈局模式的「默認」對齊方式
<align-self>/<justify-self>
- 第一個值設置 align-self
,第二個值設置 justify-align
。若是缺乏第二個值,則對兩個屬性都生效。
舉例:
.item-a {
place-self: center;
}
複製代碼
.item-a {
place-self: center stretch;
}
複製代碼
全部主流瀏覽器(除了 Edge
)都支持 place-self
簡寫屬性。
px
、rem
、%
等,你還可使用 min-content
、max-content
、auto
關鍵字,但最有用的是 fr
單位。grid-template-columns: 200px 1fr 2fr min-content;
fr
)的邊界。好比設置列爲 1fr
,但縮小到最小 200px
:grid-template-columns: 1fr minmax(200px, 1fr);
repeat()
函數,節省一些字符。好比 10 列同樣的寬度:grid-template-columns: repaet(10, 1fr);
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
以爲對你有幫助的話,歡迎 star 個人博客!