本文基于阮一峰大神的文章 http://www.ruanyifeng.com/blog/2019/03/grid-layout-tutorial.html
真誠建議大家去原文看,這篇文是我自己根據阮一峰的文章提煉要點,類似于自己的筆記和感悟。
下面開始正題:
grid 中文意思是網格,所以我們可以想象出,它大概是下面這個樣子:
每一個方塊可以調,每一根線可以調,方塊與方塊的間距也可以調。
(下面所有的示例,我先給一個完整代碼,剩下的就簡化了,方便大家查看)
一、方塊大小如何調?
方塊的大小說到點子上,也就是方塊的width
和 height
。調節width
和 height
,基本就三種方式:
- 絕對值,如 100px,10rem,10vh,10vw等。
- 百分比,如 50%
- 絕對值+百分比,如 calc(42% - 0.5rem) 等。(推薦大家去看看
calc
,很好用哦~)
(如果還有其他方式,歡迎大家評論中雅正)
1. 在父元素上操作
1.1 首先,父元素要聲明自己是個grid布局的元素(塊級或行內級):
- 塊級
.container{
display: grid; /* 一個塊級的grid布局元素,展示效果為另起一行 */
}
效果圖如下:
- 行內級
.container{
display: inline-grid; /* 一個行內的grid布局元素,展示效果為與其他行內元素在一行*/
}
效果圖如下:
1.2 聲明完grid之后,要操作行和列
-
grid-template-columns
控制每一列的寬度 -
grid-template-rows
控制每一行的高度
這兩個屬性的屬性值可以有多種方式,下面我會一一舉例
1.2.1 絕對值
比如 100px 10rem等具體的值。如下代碼:
一個三列兩行的網格,這個很好理解,大家仔細看代碼
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<style>
.container{
color: #fff;
text-align: center;
display: grid;
grid-template-columns: 100px 200px 100px; /* 三列 */
grid-template-rows: 200px 100px; /* 兩行 */
}
.item:nth-child(1){background: #00aa00;}
.item:nth-child(2){background: #0000ff;}
.item:nth-child(3){background: #ff5500;}
.item:nth-child(4){background: #ff00ff;}
.item:nth-child(5){background: #aa0000;}
.item:nth-child(6){background: #55007f;}
</style>
</head>
<body>
<div class="container">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
<div class="item">5</div>
<div class="item">6</div>
</div>
</body>
</html>
效果圖如下:
1.2.2 百分比
注意,如果行的控制上也用百分比的話,grid元素要先設置height
height:300px;
grid-template-columns: 20% 50% 30%; /* 三列 */
grid-template-rows: 30% 70%; /* 兩行 */
效果圖如下:
1.2.3 大招:一些神奇的屬性值
1.2.3.1 repeat()
看這個屬性設定
grid-template-columns: 100px 100px 100px; /* 三列 */
上面列數小,只有3列,所以可以枚舉出來。但如果列數大了呢?比如12列,我們也枚舉出來?是不是有點傻?
repeat() 就可以解決這個問題
repeat()接受兩個參數,第一個參數是重復的次數(上例是3),第二個參數是所要重復的值
所以可以寫成
grid-template-columns: repeat(3,100px); /* 絕對值 */
grid-template-columns: repeat(3,33.33%); /* 百分比 */
grid-template-columns: repeat(3,20px 50px 30px); /* 重復三遍模式,一共9列 */
1.2.3.2 auto-fill
有時候,里面的小格子大小固定,但外面的大容器大小不固定,想要小格子盡可能填充滿大容器的每一行或每一列,這時可以用到auto-fill
先看充滿一行:
grid-template-columns: repeat(auto-fill, 130px); /* 盡可能充滿一行 */
效果圖:
充滿一列
height: 500px;
grid-auto-flow: column; /* 先確定按列排 */
grid-template-rows: repeat(auto-fill, 120px);
效果圖:
1.2.3.3 fr
網格布局提供了fr關鍵字(fraction 的縮寫,意為"片段")。如果兩列的寬度分別為1fr和2fr,就表示后者是前者的兩倍。
個人認為單純使用fr來表示比例沒有任何意義,和百分比效果一樣,頂多是寫法上更方便一些,因為不用計算百分比。fr和絕對值配合使用,才會發揮出巨大的作用
比如說,現在有這么個需求:一個div,寬度隨屏幕自適應,里面有三個元素排成一行,第一個元素100px的寬度,第三個元素寬度是第二個的二倍,要求三個元素充滿整個div。我們就可以使用fr來實現。
grid-template-columns: 100px 1fr 2fr;
效果圖如下:
1.2.3.4 minmax()
設置最小最大的范圍。
grid-template-columns: 100px 100px minmax(120px ,1fr);
1.2.3.5 auto
經常適用于以下場景:
一個div,寬度隨屏幕自適應,里面三個元素排成一行,第一個和第三個各100px,第二個充滿剩余空間
grid-template-columns: 100px auto 100px;
效果圖如下:
二、網格線
1. 指定網格線名稱
grid-template-columns屬性和grid-template-rows屬性里面,還可以使用方括號,指定每一根網格線的名字,方便以后的引用
grid-template-columns: [cl1] 100px [cl2] auto [cl3] 100px [cl4];
grid-template-rows: [rl1] 100px [2l2] auto [rl3];
三、方塊與方塊的間距
- 設置列間距
column-gap
- 設置行間距
row-gap
- gap: <row-gap> <column-gap>; 前兩者簡寫形式
grid-template-columns: [cl1] 100px [cl2] auto [cl3] 100px [cl4];
grid-template-rows: [rl1] 100px [2l2] auto [rl3];
column-gap: 10px;
row-gap: 20px;
效果圖:
四、布局相關
1. grid-template-areas
grid布局會分出很多小單元格,這個屬性就可以給單元格命名,方便引用
display: grid;
grid-template-columns: 100px 100px 100px;
grid-template-rows: 100px 100px 100px;
grid-template-areas: 'a b c'
'd e f'
'g h i';
如上代碼,九個單元格按照位置命名了。
如果有些單元格,我們不需要引用,那么就不需要命名,該相對位置就用.
代替:
grid-template-areas: 'a . c'
'd e .'
'g . i';
2. grid-auto-flow
默認排列單元格的方式
- 按行排: grid-auto-flow: row;
- 按列排: grid-auto-flow: column;
像不像flex布局里的 flex-direction
grid-auto-flow: column;
grid-template-columns: 50px auto 50px ;
grid-template-rows: 50px auto ;
效果圖如下(仔細體會行和列哦,并沒有改變,只是排列方式變了):
** 有一個 dense ** 的東西,指定某個單元格放在確定位置,其他的如何擺放,說實話我覺得用處不大,先不寫了。
3. justify-items、align-items 、place-items
- justify-items:單元格內容的水平位置
主要有四個值:stretch | start | end | center。
stretch是默認值,拉伸,占滿整個單元格位置。
給大家看一個start的完整代碼。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
<style type="text/css">
#container{
display: grid;
grid-template-columns: 100px 100px 100px;
grid-template-rows: 100px 100px 100px;
justify-items: start; /* start 布局 */
}
.item {
font-size: 2em;
text-align: center;
border: 1px solid #000;
}
.item-1 {background-color: #ef342a;}
.item-2 {background-color: #f68f26;}
.item-3 {background-color: #4ba946;}
.item-4 {background-color: #0376c2;}
.item-5 {background-color: #c077af;}
.item-6 {background-color: #f8d29d;}
.item-7 {background-color: #b5a87f;}
.item-8 {background-color: #d0e4a9;}
.item-9 {background-color: #4dc7ec;}
</style>
</head>
<body>
<div id="container">
<div class="item item-1">1</div>
<div class="item item-2">2</div>
<div class="item item-3">3</div>
<div class="item item-4">4</div>
<div class="item item-5">5</div>
<div class="item item-6">6</div>
<div class="item item-7">7</div>
<div class="item item-8">8</div>
<div class="item item-9">9</div>
</div>
</body>
</html>
效果圖:
- align-items:單元格內容的垂直位置,與上面的justify-items 同理。
- place-items:前面兩者的合稱
4. justify-content、align-content、place-content
- justify-content: 內容區域(那些聚在一起的單元格)在整個容器內水平方向的布局
取值:start | end | center | stretch | space-around | space-between | space-evenly;
start是默認值。
舉一個center的例子,下面是完整代碼:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
<style type="text/css">
#container{
display: grid;
width: 500px;
height: 500px;
border: 1px solid #000000;
grid-template-columns: 100px 100px 100px;
grid-template-rows: 100px 100px 100px;
justify-content: center;
}
.item-1 {background-color: #ef342a;}
.item-2 {background-color: #f68f26;}
.item-3 {background-color: #4ba946;}
.item-4 {background-color: #0376c2;}
.item-5 {background-color: #c077af;}
.item-6 {background-color: #f8d29d;}
.item-7 {background-color: #b5a87f;}
.item-8 {background-color: #d0e4a9;}
.item-9 {background-color: #4dc7ec;}
</style>
</head>
<body>
<div id="container">
<div class="item item-1">1</div>
<div class="item item-2">2</div>
<div class="item item-3">3</div>
<div class="item item-4">4</div>
<div class="item item-5">5</div>
<div class="item item-6">6</div>
<div class="item item-7">7</div>
<div class="item item-8">8</div>
<div class="item item-9">9</div>
</div>
</body>
</html>
效果圖:
- align-content : 內容區域(那些聚在一起的單元格)在整個容器內水平方向的布局
- place-content屬性是align-content屬性和justify-content屬性的合并簡寫形式。
5. grid-auto-columns、grid-auto-rows
比如網格只有3列,但是某一個項目指定在第5行。這時,瀏覽器會自動生成多余的網格,以便放置項目。
一個代碼示例:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
<style type="text/css">
#container{
display: grid;
width: 500px;
height: 500px;
border: 1px solid #000000;
grid-template-columns: 100px 100px 100px;
grid-template-rows: 100px 100px 100px;
}
.item-1 {background-color: #ef342a;}
.item-2 {background-color: #f68f26;}
.item-3 {background-color: #4ba946;}
.item-4 {background-color: #0376c2;}
.item-5 {background-color: #c077af;}
.item-6 {background-color: #f8d29d;}
.item-7 {background-color: #b5a87f;}
.item-8 {background-color: #d0e4a9;}
.item-9 {background-color: #4dc7ec;}
.item-1{
grid-row-start: 4;
grid-row-start: 5;
}
</style>
</head>
<body>
<div id="container">
<div class="item item-1">1</div>
<div class="item item-2">2</div>
<div class="item item-3">3</div>
<div class="item item-4">4</div>
<div class="item item-5">5</div>
<div class="item item-6">6</div>
<div class="item item-7">7</div>
<div class="item item-8">8</div>
<div class="item item-9">9</div>
</div>
</body>
</html>
效果圖:
6. grid-column-start、grid-column-end、grid-row-start、grid-row-end
指定某一項目的四個邊框,從而指定某一項目的具體位置,如下代碼:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
<style type="text/css">
#container{
display: grid;
grid-template-columns: 100px 100px 100px ;
grid-template-rows: 100px 100px 100px ;
}
.item-1 {background-color: #ef342a;}
.item-2 {background-color: #f68f26;}
.item-3 {background-color: #4ba946;}
.item-4 {background-color: #0376c2;}
.item-5 {background-color: #c077af;}
.item-6 {background-color: #f8d29d;}
.item-7 {background-color: #b5a87f;}
.item-8 {background-color: #d0e4a9;}
.item-9 {background-color: #4dc7ec;}
.item-1{
/* 指定位置 */
grid-row-start: 2;
grid-row-end: 3;
grid-column-start: 2;
grid-column-end: 3;
}
</style>
</head>
<body>
<div id="container">
<div class="item item-1">1</div>
<div class="item item-2">2</div>
<div class="item item-3">3</div>
<div class="item item-4">4</div>
<div class="item item-5">5</div>
<div class="item item-6">6</div>
<div class="item item-7">7</div>
<div class="item item-8">8</div>
<div class="item item-9">9</div>
</div>
</body>
</html>
效果圖:
7. grid-area
指定項目放在哪一個區域,主要有兩種方法
7.1 直接指定區域
#container{
display: grid;
grid-template-columns: 100px 100px 100px ;
grid-template-rows: 100px 100px 100px ;
grid-template-areas: 'a b c'
'd e f'
'g h i';
}
.item-1{
grid-area: f; /* 直接指定 */
}
7.2 通過線來指定區域
#container{
display: grid;
grid-template-columns: 100px 100px 100px ;
grid-template-rows: 100px 100px 100px ;
}
.item-1{
grid-area: 2/3/3/4;
}
8. justify-self、align-self、place-self
設置單元格內容的水平或垂直位置,只作用于單個項目
太簡單了。。。跟上面justify-items一樣的原理。
到這兒就算完了,太不容易了,好懵。。。