Grid布局指南


簡介

CSS網格布局(又稱“網格”),是一種二維網格布局系統。CSS在處理網頁布局方面一直做的不是很好。一開始我們用的是table(表格)布局,然后用float(浮動),position(定位)和inline-block(行內塊)布局,但是這些方法本質上是hack,遺漏了很多功能,例如垂直居中。后來出了flexbox(盒子布局),解決了很多布局問題,但是它僅僅是一維布局,而不是復雜的二維布局,實際上它們(flexbox與grid)能很好的配合使用。Grid布局是第一個專門為解決布局問題而創建的CSS模塊,2012年11月06日成立草案

初步了解和瀏覽器支持
使用Grid布局非常簡單,你只需要給容器(container)定義:display:grid,並設置列(grid-template-columns)和 行(grid-template-rows)的大小,然后用grid-column和grid-row定義容器子元素(grid-item項目)的位置。與flexbox布局類似,一開始項目的排列順序並不重要,可以放置在容器的任何位置,這也使得你非常容易通過媒體查詢重新排列你的項目。想象一下,當你定義整個頁面的布局時,你只需要幾行CSS就可以完成頁面重排以便適應各種屏幕寬度,這得有多么神奇!
好東西總是來的晚,不要焦躁,不要沮喪。活好每一天,自然就等到了。
目前瀏覽器還不支持Grid布局,IE10和IE11支持老的語法。如果你想體驗Grid布局的強大,推薦使用開通過“體驗新功能”的Chrome, Opera 或 Firefox, Chrome:打開瀏覽器,輸入chrome://flags,找到"experimental web platform features",啟用並重啟瀏覽器;Opera:輸入opera://flags,與Chrome一樣;Firefox:輸入layout.css.grid.enabled。

瀏覽器支持情況:

Chrome|Safari|Firefox|Opera|IE|Android/iOS
-|-|--|-|-
29+ (Behind flag)|Not supported|40+ (Behind flag)|28+ (Behind flag)|10+ (Old syntax)|Not supported

重要術語
在深入了解Grid布局概念之前,我們先了解一些術語。因為這些術語在概念上很相似,如果你不記住Grid定義的含義,會很容易將它們混淆,但是不用擔心,這里術語很少。

1.網格容器(Grid Container)
元素應用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> 

2.網格項(Grid Item)
網格容器的子元素,下面的item元素是網格項,但sub-item不是。

<div class="container"> <div class="item"></div> <div class="item"> <p class="sub-item"></p> </div> <div class="item"></div> </div> 

3.網格線(Grid Line)
組成網格線的分界線。它們可以是列網格線(column grid lines),也可以是行網格線(row grid lines)並且居於行或列的任意一側,下面黃色線就是列網格線。

 
grid lines

4.網格軌道(Grid Track)
兩個相鄰的網格線之間為網格軌道。你可以認為它們是網格的列或行,下面在第二個和第三個網格線之間的黃色部分為網格軌道。

 
Grid Track

5.網格單元(Grid Cell)
兩個相鄰的列網格線和兩個相鄰的行網格線組成的是網格單元,它是最小的網格單元。下面行網格線1(row grid lines 1)、行網格線2(row grid lines 2)和列網格線2(column grid lines 2)、列網格線3(column grid lines 3)組成的黃色區域為網格單元。

 
Grid Cell

6.網格區(Grid Area)
網格區是由任意數量網格單元組成,下面行網格線1(row grid lines 1)、行網格線3(row grid lines 3)和列網格線1(column grid lines 1)、列網格線3(column grid lines3)組成的黃色區域為網格區。

 
Grid Area

設置在網格容器上的屬性

  • display
  • grid-template-columns
  • grid-template-rows
  • grid-template-areas
  • grid-column-gap
  • grid-row-gap
  • grid-gap
  • justify-items
  • align-items
  • justify-content
  • align-content
  • grid-auto-columns
  • grid-auto-rows
  • grid-auto-flow
  • grid

1. display: grid | inline-grid | subgrid;

屬性值:
grid: 生成塊級網格
inline-grid: 生成行內網格
subgrid: 如果網格容器本身是網格項(嵌套網格容器),此屬性用來繼承其父網格容器的列、行大小。

注:當元素設置了網格布局,column、float、clear、vertical-align屬性無效。

2. grid-template-columns: <track-size> ... | <line-name> <track-size> ... ;
grid-template-rows: <track-size> ... | <line-name> <track-size> ... ;

設置行和列的大小,在行軌道或列軌道兩邊是網格線。

屬性值:
track-size: 軌道大小,可以使用css長度,百分比或用分數(用fr單位)。
line-name: 網格線名字,你可以選擇任何名字。

例子:
當你設置行或列大小為auto時,網格會自動分配空間和網格線名稱。

.container{ display:grid; grid-template-columns: 40px 50px auto 50px 40px; grid-template-rows: 25% 100px auto; } 
 
grid-numbers

你也可以給網格線定義名字,注意名字需要寫在[]里面。

.container{ display:grid; 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]; } 
 
grid-names

每條網格線可以有多個名字,例如上面行的第二條線有兩個名字,分別是row1-end和row2-start。

.container{ display:grid; grid-template-rows: [row1-start] 25% [row1-end row2-start] 25% [row2-end]; } 

如果你定義包含重復部分,可以使用repeat()簡化。

.container{ display:grid; grid-template-columns: repeat(3, 20px [col-start]) 5%; } 

上面等同於下面:

.container{ display:grid; grid-template-columns: 20px [col-start] 20px [col-start] 20px [col-start] 5%; } 

用fr單位可以將容器分為幾等份,例如下面分成三等份。

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

如果fr單位和實際值一起使用,設置fr的行或列將分(除了實際值)剩余部分。

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

3.grid-template-areas

通過獲取網格項中的grid-area屬性值(名稱),來定義網格模版。重復網格區(grid-area)名稱將跨越網格單元格,‘.’代表空網格單元。

屬性值:
grid-area-name: 網格項的grid-area屬性值(名字)
‘.’ : 空網格單元
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" } 

上面代碼示例會創建四列三行網格,第一行將是header,第二行前兩個網格單元是main部分、第三個為空網格單元、第四個為sliderbar,第三行是footer。

 
grid-template-areas

4. grid-column-gap:<line-size>; 和 grid-row-gap: <line-size> ;

網格單元間距。

屬性值:
line-size: 網格線間距,設置單位值。

例子:

.container{ display:grid; grid-template-columns: 100px 50px 100px; grid-template-rows: 80px auto 80px; grid-column-gap: 10px; grid-row-gap: 15px; } 
 
grid-column-row-gap

注:間隔僅僅作用在網格單元之間,不作用在容器邊緣。

5. grid-gap:<grid-row-gap> <grid-column-gap>;

是grid-column-gap 和 grid-row-gap簡寫。

例子:

.container{ display:grid; grid-template-columns: 100px 50px 100px; grid-template-rows: 80px auto 80px; grid-gap: 10px 15px; } 

注:如果只設置一個值,那么grid-column-gap 和 grid-row-gap都為那個值。

6. justify-items: start | end | center | stretch(默認) ;

垂直於列網格線對齊,適用於網格容器里的所有網格項。

屬性值:
start: 左對齊。
end: 右對齊。
center: 居中對齊。
stretch: 填滿(默認)。

例子:

.container{ display:grid; justify-items: start; } 
 
grid-justify-items-start
.container{ display:grid; justify-items: end; } 
 
grid-justify-items-end
.container{ display:grid; justify-items: center; } 
 
grid-justify-items-center
.container{ display:grid; justify-items: stretch; } 
 
grid-justify-items-stretch

7. align-items: start | end | center | stretch ;

垂直於行網格線對齊,適用於網格容器里的所有網格項。

屬性值:
start: 頂部對齊。
end: 底部對齊。
center: 居中對齊。
stretch:填滿(默認)。

例子:

.container{ display:grid; align-items: start; } 
 
grid-align-items-start
.container{ display:grid; align-items: end; } 
 
grid-align-items-end
.container{ display:grid; align-items: center; } 
 
grid-align-items-center
.container{ display:grid; align-items: stretch; } 
 
grid-align-items-stretch

8. justify-content: start | end | center | stretch | space-around | space-between | space-evenly ;

如果用像px非彈性單位定義的話,總網格區域大小有可能小於網格容器,這時候你可以設置網格的對齊方式(垂直於列網格線對齊)。

屬性值:
start: 左對齊。
end: 右對齊。
center: 居中對齊。
stretch: 填滿網格容器。
space-around: 網格項兩邊間距相等,網格項之間間隔是單側的2倍。
space-between: 兩邊對齊,網格項之間間隔相等。
space-evenly: 網格項間隔相等。

例子:

.container{ display:grid; justify-content: start; } 
 
grid-justify-content-start
.container{ display:grid; justify-content: end; } 
 
grid-justify-content-end
.container{ display:grid; justify-content: center; } 
 
grid-justify-content-center
.container{ display:grid; justify-content: stretch; } 
 
grid-justify-content-stretch
.container{ display:grid; justify-content: space-around; } 
 
grid-justify-content-space-around
.container{ display:grid; justify-content: space-between; } 
 
grid-justify-content-space-between
.container{ display:grid; justify-content: space-evenly; } 
 
grid-justify-content-space-evenly

9. align-content: start | end | center | stretch | space-around | space-between | space-evenly ;

如果用像px非彈性單位定義的話,總網格區域大小有可能小於網格容器,這時候你可以設置網格的對齊方式(垂直於行網格線對齊)。

屬性值:
start: 頂部對齊。
end: 底部對齊。
center: 居中對齊。
stretch: 填滿網格容器。
space-around: 網格項兩邊間距相等,網格項之間間隔是單側的2倍。
space-between: 兩邊對齊,網格項之間間隔相等。
space-evenly: 網格項間隔相等。

例子:

.container{ display:grid; align-content: start; } 
 
grid-align-content-start
.container{ display:grid; align-content: end; } 
 
grid-align-content-end
.container{ display:grid; align-content: center; } 
 
grid-align-content-center
.container{ display:grid; align-content: stretch; } 
 
grid-align-content-stretch
.container{ display:grid; align-content: space-around; } 
 
grid-align-content-space-around
.container{ display:grid; align-content: space-between; } 
 
grid-align-content-space-between
.container{ display:grid; align-content: space-evenly; } 
 
grid-align-content-space-evenly

10. grid-auto-columns: <track-size> ... ; 和 grid-auto-rows: <track-size> ... ;

自動生成隱式網格軌道(列和行),當你定位網格項超出網格容器范圍時,將自動創建隱式網格軌道。

屬性值:
track-size: 網格軌道大小,可以是固定值,百分比或者是分數(fr單位)。

為了說明隱式網格軌道是怎么創建的,我們先看下面列子:

.container{ display:grid; grid-template-columns: 60px 60px; grid-template-rows: 90px 90px } 
 
grid-auto

這是2✖️2的網格,但是我們來用grid-column 和 grid-row給網格項定位如下:

.item-a{ grid-column: 1 / 2; grid-row: 2 / 3; } .item-b{ grid-column: 5 / 6; grid-row: 2 / 3; } 
 
implicit-tracks

我們可以看出,網格項item-b定位在第五根列網格線(column line 5 )和第六根列網格線(column line 6 )之間。但是我們網格容器根本不存在這兩條網格線,所以就用兩個0寬度來填充。在這里我們可以用網格自動行(grid-auto-rows)和網格自動列(grid-auto-columns)來定義這些隱式軌道寬度。

.container{ display:grid; grid-auto-columns: 60px; } 
 
implicit-tracks-with-widths

11. grid-auto-flow : row(默認) | column | dense ;

在沒有設置網格項的位置時,這個屬性控制網格項怎樣排列。

屬性值:
row: 按照行依次從左到右排列。
column: 按照列依次從上倒下排列。
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> 

下面定義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,item-b、item-c和item-d在行上是從左到右排列,如下:

 
grid-auto-flow-row

如果我們設置 grid-auto-flow: column;結果如下:

 
grid-auto-flow-column

12. grid: none | <grid-template-rows> / <grid-template-columns> | <grid-auto-flow> [<grid-auto-rows> [ / <grid-auto-columns>] ];

是一種簡寫形式,設置網格容器所有屬性。

屬性值:
none: 設置為所有屬性的默認值。
<grid-template-rows> / <grid-template-columns>: 設置行和列的值,其他屬性為默認值。
<grid-auto-flow> [ <grid-auto-rows> [ / <grid-auto-columns>] ] : 設置網格自動流、網格自動行、網格自動列的值,其他未設置則為默認值。

例子1:

.container{ grid: 200px auto / 1fr auto 1fr; } 等同於 .container{ grid-template-rows: 200px auto; grid-template-columns: 1fr auto 1fr; grid-template-areas: none; } 

例子2:

.container{ grid: column 1fr / auto; } 等同於 .container{ grid-auto-flow: column; grid-auto-rows: 1fr; grid-auto-columns: auto; } 

設置在網格項上的屬性

  • grid-column-start
  • grid-column-end
  • grid-row-start
  • grid-row-end
  • grid-column
  • grid-row
  • grid-area
  • justify-self
  • align-self

 

1. 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 ;

通過網格線來定義網格項的位置。grid-column-start、grid-row-start定義網格項的開始位置,grid-column-end、grid-row-end定義網格項的結束位置。

屬性值:
line: 指定帶編號或者名字的網格線。
span <number>: 跨越軌道的數量。
span <name>: 跨越軌道直到對應名字的網格線。
auto: 自動展示位置,默認跨度為1。

例子:

.item-a{ grid-column-start: 2; grid-column-end: five; grid-row-start: row1-start grid-row-end: 3 } 
 
grid-start-end-a
.item-b{ grid-column-start: 1; grid-column-end: span col4-start; grid-row-start: 2 grid-row-end: span 2 }
grid-start-end-a

注:如果未聲明grid-column-end或grid-row-end,默認將跨越一個軌道。項目也可以重疊,設置z-index來確定堆疊順序。

2. grid-column: <start-line> / <end-line> | <start-line> / span <value> ;
     grid-row: <start-line> / <end-line> | <start-line> / span <value> ;

是 grid-column-start、grid-column-end 和 grid-row-start、grid-row-end 的簡寫。

例子:

.item-c{ grid-column: 3 / span 2; grid-row: third-line / 4; }
grid-start-end-c

3. grid-area: <name> | <row-start> / <column-start> / <row-end> / <column-end> ;

定義網格項名字,以便創建模塊(容器屬性grid-template-areas來定義模塊)。

屬性值:
name: 項目名子。
<row-start> / <column-start> / <row-end> / <column-end>: 可以是數字或網格線名字。

例子:
定義網格項名字:

.item-d{ grid-area: header } 

通過網格線定位網格項:

.item-d{ grid-area: 1 / col4-start / last-line / 6 ; }
grid-start-end-d

4. justify-self: justify-self: start | end | center | stretch;

定義單個網格項垂直於列網格線的對齊方式。

屬性值:
start: 網格區域左對齊。
end: 網格區域右對齊。
center: 網格區域居中。
stretch: 網格區域填滿。

例子:

.item-a{ justify-self: start; } 
 
grid-justify-self-start
.item-a{ justify-self: end; } 
 
grid-justify-self-end
.item-a{ justify-self: center; } 
 
grid-justify-self-center
.item-a{ justify-self: stretch; } 
 
grid-justify-self-stretch

提示:也可以在容器上設置justify-items,達到全部網格項對齊。

5. align-self: start | end | center | stretch;

定義單個網格項垂直於行網格線的對齊方式。

屬性值:
start: 網格區域頂部對齊。
end: 網格區域底部對齊。
center: 網格區域居中。
stretch: 網格區域填滿。

例子:

.item-a{ align-self: start; } 
 
grid-align-self-start
.item-a{ align-self: end; } 
 
grid-align-self-end
.item-a{ align-self: center; } 
 
grid-align-self-center
.item-a{ align-self: stretch; } 
 
grid-align-self-stretch

提示:也可以在容器上設置align-items,達到全部網格項對齊。

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM