一勞永逸的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-column-gap> <grid-row-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,達到全部網格項對齊。

結束

這篇文章翻譯自A Complete Guide to Grid,作者是CHRIS HOUSE。裏面也加入了一些我個人的理解。文章有點長,屬性容易混淆,邊看邊練習會比較容易理解和記住。

本文來自博客: https://www.jianshu.com/p/d183265a8dad

古人學問無遺力,少壯工夫老始成。
紙上得來終覺淺,絕知此事要躬行。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章