CSS Grid Layout 從入門到入門
CSS 的 Grid Layout 已經開始在瀏覽器上有資詞啦!
可以看到在 FF 的52版本以上已經支持了,Chrome 從57開始支持,如果用 dev 版本或者 canary 版本都可以了,safari 包括10.1和 tp 版都已經支持了。
可以愉快的搞起來啦。
友情提醒,如果想看到某些代碼的效果,請在上文提到的支持 Grid 的瀏覽器中查看本文,移動端瀏覽器通通不支持。
基本概念
一個 Grid 其實就是由一系列相交的線組成的結構,其主要的概念如下
- grid lines 組成 grid 的線,垂直或者水平,并且從1開始計數
- grid tracks 在 grid 中的行和列,其中水平的為行(row),豎直的為列(column)
- grid cells 行和列的交點
- grid area 由一系列相鄰的 cells 組成的長方形區域
創建一個 Grid
首先就是一個新的 display 值,叫做 grid 。
將某個元素的 display 設置為 grid 就可以創建一個 grid layout 了。
<div class="grid">
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
</div>
然后寫點 CSS
.grid {
display: grid;
grid-template-columns: 100px 100px 100px 100px;
grid-template-rows: 100px 100px;
grid-gap: 20px;
}
.grid div {
background-color: grey;
}
然后就可以看到如下效果啦:
See the Pen aJypqZ by Yang Cong ( @nighting ) on CodePen .
grid-template-columns 屬性,定義了 grid 的各個列的寬度
grid-template-rows 屬性,定義了grid 的各個行的高度
這樣就可以畫出一整個 grid 了
而 grid-gap 屬性,定義了各個 grid cells 之間的距離
自適應的 Grid
如你發現,上面的定義只是創建了一個 grid,并沒能自適應屏幕。
Grid 標準引入了一個新的單位,fr,我們可以使用 fr 單位來做自適應。
1fr 是一個『分數單位』,用來表示『元素剩余的空間』 — MDN
.grid {
display: grid;
grid-template-columns: 1fr 1fr 1fr 1fr;
grid-template-rows: 200px 200px;
grid-gap: 20px;
}
.grid div:nth-child(2n) {
background-color: darkgrey;
}
.grid div:nth-child(2n+1) {
background-color: grey;
}
效果如下
See the Pen ZeJerK by Yang Cong ( @nighting ) on CodePen .
minmax()
我們可能不單單需要一個簡單的長度,也不一定需要某個元素無限擴大或收縮。這時候就可以使用 minmax 函數,這個函數接收兩個參數,分別是 min 和 max 的長度,比如
grid-template-columns: minmax(300px, 1fr) minmax(200px, 400px) 300px;
效果如下
使用 repeat()
你可能也發現了,如果我需要四列,那我需要寫4個長度,如果需要100列……天吶,無法想象。機智的勞動人民怎么會允許這種事情的發生,于是隨帶著 Grid 一起的還有個CSS函數,repeat()
repeat(times:Number, length:Length)
如下
- repeat(4, 1pr) === 1pr 1pr 1pr 1pr
- repeat(3, 100px) === 100px 100px 100px
因此上面的 CSS 也可以改寫成如下:
.grid {
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-template-rows: repeat(2, 200px);
grid-gap: 20px;
}
效果還是如上!
auto-fit & auto-fill
有時候我們并不需要確定行數和列數,可能我們希望能根據瀏覽器的窗口大小來自動的適應。這時候我們就會用到 auto-fill 和 auto-fit 屬性。兩者的區別我也不是很清楚,貌似 auto-fill 會盡可能多得去增加行數和列數,而 auto-fit 則相反。
我們可以看到下面兩張圖的差別:
以及
從表現上看,auto-fit 不會產生空的行或者列。
template areas
Grid 還提供了一種用于排版的方法,也就是 template areas,手動得將想要的layout 設置,而且還是『可視化』的哦
具體代碼如下
<div class="grid">
<header class="box"></header>
<aside class="box"></aside>
<article class="box"></article>
<footer class="box"></footer>
</div>
這是我們很常見的頭部+導航+主要內容+底部的布局
header {
grid-area: hd;
background-color: #ff2e9c;
}
aside {
grid-area: sidebar;
background-color: #61dae4;
}
article {
grid-area: at;
background-color: #73d545;
}
footer {
grid-area: ft;
background-color: #f2ee3e;
}
.grid {
display: grid;
grid-gap: 20px;
grid-template-rows: 50px 400px 50px;
grid-template-areas:
"hd hd"
"sidebar at"
"sidebar ft";
}
.box {
border-radius: 8px;
}
最主要的代碼就是 grid-template-areas 這個屬性啦,里面的值生動得呈現了最終的效果。
定位和占位
有時候我們并不想按照特定的順序來排列,也有某些部分想要更多的 cell
我們可以使用屬性 grid-column-start 和 grid-column-end 以及對應的 grid-row-start 和 grid-row-end 來進行定位和占位
為了方便,我們可以使用縮寫屬性 grid-column 和 grid-row
<div class="grid">
<div id="a"></div>
<div id="b"></div>
</div>
.grid {
display: grid;
grid-template-columns: repeat(5, 100px);
grid-template-rows: repeat(5, 100px);
grid-gap: 20px;
}
#a {
background-color: #ff2e9c;
grid-column: 2 / 3;
grid-row: 3 / 4;
}
#b {
background-color: #61dae4;
grid-column: 3 / 5;
grid-row: 2 / span 3;
}
最終的結果是醬的:
See the Pen NpvjMa by Yang Cong ( @nighting ) on CodePen .
其中出現了一個 span 的值,表示跨度。
還記得開頭出現的 gird lines 嗎,是從1開始計數的,這里我們定位的值即是 grid lines 的標號。
比如 grid-row: 2 / span 3 ,表示該元素縱向從第二根線開始,并且占據3個 cell。
對齊
align-content 和 justify-content
justify-content 用于定義 grid 在水平方向 如何對齊
align-content 用于定義 grid 在垂直方向 如何對齊
他們有如下幾個值
- start
- center
- end
- space-between
- space-around
- space-evenly
- stretch
具體表現如下:
DOM結構
<div class="grid">
<div></div>
<div></div>
<div></div>
<div></div>
</div>
CSS
.grid {
display: grid;
grid-template-rows: 100px 100px;
grid-template-columns: 150px 150px 150px;
height: 500px;
width: 650px;
border: 1px solid grey;
}
.grid div:nth-child(1) {
grid-column: 1 / 3;
grid-row: 1;
background-color: #ff2e9c;
}
.grid div:nth-child(2) {
gird-column: 1;
grid-row: 2;
background-color: #61dae4;
}
.grid div:nth-child(3) {
gird-column: 2;
grid-row: 2;
background-color: #73d545;
}
.grid div:nth-child(4) {
gird-column: 3;
grid-row: 1 / 3;
background-color: #f2ee3e;
}
- align-content: strat; justify-content: start;
- align-content: center; justify-content: center;
- align-content: end; justify-content: end;
- align-content: center; justify-content: space-evenly;
- align-content: space-around; justify-content: center;
- align-content: space-between; justify-content: center;
justify-self 和 align-self
justify-self 用于定義grid 內元素在水平方向的排列
align-self 用于定于 grid 內元素在垂直方向的排列
有如下幾種值
- start
- end
- center
- stretch 默認值
使用和效果如下:
See the Pen ZeJdvg by Yang Cong ( @nighting ) on CodePen .
這倆屬性是用在子元素上的,如果想給某個 grid 內的所有元素統一添加,可以使用
- align-items
- justify-items
這兩個屬性
在 webkit 官網的介紹中也有這樣一張能夠一目了然的圖
從入門到入門
有了 Grid 布局,我們可以很方便得完成非常多復雜的布局。
譬如之前研究過的雙飛翼布局和圣杯布局,通過 Grid 來寫的話,是非常方便的。
再譬如一些非常復雜的圖文混排的布局,grid 也可以非常輕松的實現。
不過現在 grid 的支持度還很低,從目前還有無數公司兼容 IE6的生態來講,想在生產環境用上 grid 仿(jiu)佛(shi)是個遙不可及的事情……
不過這也抵不住前端汪折騰的心啊。
來自:http://nighting.me/2017/03/14/CSS-Grid-Layout-從入門到入門/