網格布局
一、什么是網格布局
網格布局,顧名思義就是像網一樣有一個個格子一樣的布局。在一個容器里面,我們可以切割成很多行很多列,形成一個個網格,從而對這些網格進行規則性的排序,使用,達到我們復雜的頁面布局效果。
Grid 布局與 Flex 布局有一定的相似性,都可以指定容器內部多個項目的位置。但是,它們也存在重大區別。
Flex 布局是軸線布局,有主軸和側軸之分,只能指定容器內子元素針對軸線的位置,可以看作是一維布局。Grid 布局則是將容器划分成"行"和"列",產生單元格,然后指定"項目所在"的單元格,可以看作是二維布局。Grid 布局遠比 Flex 布局強大。
二.網格布局的使用
1.grid基本屬性
網格容器和項目
首先,我們要知道網格布局也是有“容器”和“項目”的,既給容器設置上display: grid;
或者display: inline-grid;
表明該容器是網格容器,這個元素的所有直系子元素將成為網格元素。
grid:指明該容器本身是塊級元素,塊級元素獨占一行。
inline-grid :指明該容器本身是一個行內元素,行內元素可以和其他行內元素共占一行。
container是一個網格容器,item為網格元素。而grandson卻不是網格元素,所以父容器只能影響兒子容器。
<div class="container">
<div class="item">
<div class="grandson"></div>
</div>
<div class="item"></div>
<div class="item"></div>
</div>
網格線 grid line
分隔網格結構的分界線。它們可以是垂直(‘列網格線’)或水平(‘行網絡線’)
網格單元 grid cell
網格單元格是指四條網格線之間的空間。所以它是最小的單位,就像表格中的單元格。
網格軌道 grid track
grid-template-columns 和 grid-template-rows 屬性來定義網格中的行和列。一個網格軌道就是網格中任意兩條線之間的空間。
就好比表格中行或列。所在在網格中其分為grid column和grid row。每個網格軌道可以設置一個大小,用來控制寬度或高度。
網格區域 grid area
多個網格線包圍的總空間。網格區域可以包含任意數量的網格單元。
2.父容器上的屬性
首先肯定是 :display: grid | inline-grid | subgrid ;
指定一個容器采用網格布局。
- grid – 生成一個塊級(block-level)網格
- inline-grid – 生成一個行級(inline-level)網格
- subgrid – 如果你的 grid container 本身就是一個 grid item(即,嵌套網格),你可以使用這個屬性來表示你想從它的父節點獲取它的行/列的大小,而不是指定它自己的大小。
1. 網格軌道寬高
grid-template-columns
屬性定義每一列的列寬,grid-template-rows
屬性定義每一行的行高。在大小前面使用數組可以定義網格線的名稱,可以有很多個名稱。可寫可不寫,看需求。
.container {
width: 200px;
height: 200px;
display: grid;
/* 定義了三列 每一行50px */
grid-template-columns: [first] 50px [line2]50px [line3]50px;
/* 定義了三行 每一行50px */
grid-template-rows: [first]50px [rowline2 line2]50px [line3]50px [end];
}
效果:
我們除了用絕對單位,還可以使用fr單位 , 一個 fr 單位代表網格容器中可用空間的一等份。也可以使用百分比,如果你定義了非常多行非常多列,還可以使用repeat()函數。也可以混合寫。例如下面
grid-template-columns: 33.33% 33.33% 33.33%;
grid-template-columns: 1fr 1fr 1fr;
grid-template-columns: repeat(3, 33.33%);//第一個參數是幾份,后面可以說絕對單位,百分比,fr
grid-template-columns: repeat(3, 50px [col-start]);//攜帶網格線名字
grid-template-columns: repeat(2, 100px 20px 80px);//重復某種模式
grid-template-columns: 30% 50px auto;
注意:混合使用單位的時候,例如下面,fr為可用寬度減去50px后,得到的空間再進行等量的分配。
grid-template-columns: 1fr 50px 1fr 1fr;
2. 網格間距
grid-row-gap
屬性設置行與行的間隔(行間距),grid-column-gap
屬性設置列與列的間隔(列間距),grid-gap
屬性是grid-column-gap
和grid-row-gap
的合並簡寫形式。grid-gap: <grid-row-gap> <grid-column-gap>
.container {
width: 200px;
height: 200px;
display: grid;
grid-template-columns: [first] 50px [line2]50px [line3]50px;
grid-template-rows: [first]50px [rowline2 line2]50px [line3]50px [end];
grid-row-gap:5px;
grid-column-gap:5px;
/* grid-gap: 5px 5px;合並寫法 */
}
效果:
3.網格區域
通過引用 grid-area-name
屬性指定的網格區域的名稱來定義網格模板。 重復網格區域的名稱導致內容擴展到這些單元格。 點號表示一個空單元格。 語法本身提供了網格結構的可視化。
定義一個2*3的網格區域,並給上名字。可以使用任意數量的相鄰的.
來聲明單個空單元格。 只要這些點號之間沒有空格,他們就代表了一個單一的單元格。
.container {
margin-left: 30%;
width: 200px;
height: 200px;
display: grid;
grid-template-columns: [first] 50px [line2]50px [line3]50px;
grid-template-rows: [first]50px [rowline2 line2]50px [line3]50px [end];
grid-row-gap:5px;
grid-column-gap:5px;
grid-template-areas: "head head "
". main"
". foot";
}
效果:
注意:
區域的命名會影響到網格線。每個區域的起始網格線,會自動命名為區域名-start
,終止網格線自動命名為區域名-end
。
比如,區域名為header
,則起始位置的水平網格線和垂直網格線叫做header-start
,終止位置的水平網格線和垂直網格線叫做header-end
。
4.網格對齊方式
justify-content
屬性是整個內容區域在容器里面的水平位置(左中右),align-content
屬性是整個內容區域的垂直位置(上中下)。
指的是整個內容在容器中的排列方式
取值有:
- start - 對齊容器的起始邊框。
- end - 對齊容器的結束邊框。
- center - 容器內部居中。
- stretch - 項目大小沒有指定時,拉伸占據整個網格容器。
- space-around - 每個項目兩側的間隔相等。所以,項目之間的間隔比項目與容器邊框的間隔大一倍。
- space-between - 項目與項目的間隔相等,項目與容器邊框之間沒有間隔。
- space-evenly - 項目與項目的間隔相等,項目與容器邊框之間也是同樣長度的間隔。
place-content
屬性是align-content
屬性和justify-content
屬性的合並簡寫形式place-content: <align-content> <justify-content>
.container {
margin-left: 30%;
width: 200px;
height: 200px;
display: grid;
grid-template-columns: repeat(3,50px);
grid-template-rows: repeat(3,50px);
grid-row-gap:5px;
grid-column-gap:5px;
background: #def1a9;
justify-content: start;
align-content: end;
}
設置一個水平靠左,垂直靠底部。效果:
設置居中
justify-content: center;
align-content: center;
5.單元格對其方式
justify-items
屬性設置單元格內容的水平位置(左中右),align-items
屬性設置單元格的垂直位置(上中下)
取值:
- start:對齊單元格的起始邊緣。
- end:對齊單元格的結束邊緣。
- center:單元格內部居中。
- stretch:拉伸,占滿單元格的整個寬度(默認值)。
使用justify-items
舉一個例子:
justify-items: start --對齊單元格的起始邊緣
justify-items: end--對齊單元格的結束邊緣
justify-items: center; --水平居中
justify-items: stretch;(默認)拉伸,占滿單元格的整個寬度。
6. grid-auto-flow
grid-auto-flow屬性控制着自動布局算法怎樣運作,精確指定在網格中被自動布局的元素怎樣排列。默認的放置順序是"先行后列",即先填滿第一行,再開始放入第二行
如果改變為:
grid-auto-flow: column;
效果:
先看看能取哪些值
grid-auto-flow: row|column|dense|row dense|column dense;
值 | 描述 |
---|---|
row | 默認值。 通過填充每一行來放置網格元素,在必要時增加新列。 |
column | 通過填充每一列來放置網格元素,在必要時增加新列。 |
dense | 該關鍵字指定自動布局算法使用一種"稠密"堆積算法,如果后面出現了稍小的元素,則會試圖去填充網格中前面留下的空白。這樣做會填上稍大元素留下的空白,但同時也可能導致原來出現的次序被打亂。 |
row dense | 按行來填充網格中前面留下的空白 |
column dense | 按列來填充網格中前面留下的空白 |
指定自動布局算法怎樣運作,精確指定在網格中被自動布局的元素怎樣排列。
什么意思呢?
當我創建了一個2*3的網格時候,我讓第三個網格占有兩個單元格寬度,代碼如下
<body>
<div class="grid-container">
<div class="item1">1</div>
<div class="item2">2</div>
<div class="item3">3</div>
<div class="item4">4</div>
</div>
</body>
<style>
* {
margin: 0px;
padding: 0px;
}
body {
height: 100%;
}
.item3 {
grid-column: auto / span 2;
}
.grid-container {
width: 300px;
height: 200px;
display: grid;
grid-template-columns: auto auto auto;
grid-template-rows: auto auto;
grid-gap: 10px;
background-color: #2196F3;
padding: 10px;
/* grid-auto-flow: row dense; */
}
.grid-container>div {
background-color: rgba(255, 255, 255, 0.8);
text-align: center;
padding: 20px 0;
font-size: 30px;
}
</style>
當我給網格容器設置上grid-auto-flow: row dense;就會填充每一行上面留下來的空白。
當我讓第三個占有三個寬度時候grid-column: auto / span 3;並設置grid-auto-flow: row ;就會補充一行,我前面只設置了2*3網格。
設置為grid-auto-flow: column;不足會補充一列。
補充:
grid-auto-columns
屬性和grid-auto-rows
屬性用來設置,瀏覽器自動創建的多余網格的列寬和行高。如果不指定這兩個屬性,瀏覽器完全根據單元格內容的大小,決定新增網格的列寬和行高。
7.grid-template屬性、grid屬性
grid-template
屬性是grid-template-columns
、grid-template-rows
和grid-template-areas
這三個屬性的合並簡寫形式。
grid
屬性是grid-template-rows
、grid-template-columns
、grid-template-areas
、 grid-auto-rows
、grid-auto-columns
、grid-auto-flow
這六個屬性的合並簡寫形式。
就我個人而言,我不喜歡簡寫,一兩個同類型簡寫還可以,多個不同屬性簡寫會導致可讀性較差。看個人咯。
3. 項目上的屬性
項目屬性,顧名思義就是定義在父容器的兒子節點上的屬性。
1. grid-column 屬性, grid-row 屬性
grid-column
屬性是grid-column-start
和grid-column-end
的合並簡寫形式,grid-row
屬性是grid-row-start
屬性和grid-row-end
的合並簡寫形式。
這就是網格最有魅力的地方,我感覺。它可以指定項目的位置放在那個地方,就是說可以放在哪個網格區域,這樣就讓布局變得靈活、復雜起來。,具體方法就是指定項目的四個邊框,分別定位在哪根網格線。
grid-column-start
屬性:左邊框所在的垂直網格線grid-column-end
屬性:右邊框所在的垂直網格線grid-row-start
屬性:上邊框所在的水平網格線grid-row-end
屬性:下邊框所在的水平網格線
例如:
<body>
<div class="container">
<div class="item1">浪</div>
<div class="item2">漫</div>
<div class="item3">主</div>
<div class="item4">義</div>
<div class="item5">碼農</div>
</div>
</body>
<style>
* {
margin: 0px;
padding: 0px;
}
body {
height: 100%;
}
.container {
width: 300px;
height: 200px;
display: grid;
grid-template-columns: repeat(3, 50px);
grid-template-rows: repeat(3,50px);
grid-gap: 5px;
background-color: #2196F3;
padding: 10px;
justify-content: center;
align-content: center;
}
.item1 {
grid-column:1 / 3;
background: #0F85CC;
}
.item2 {
grid-row: 1 / 3;
grid-column: 3 / 4;
background: #1fe605;
}
.item3 {
grid-row: 2/4;
grid-column: 1/2;
background: burlywood;
}
.item4 {
grid-row: 3/4;
grid-column: 2/4;
background: #10caf9;
}
.item5 {
border-radius: 50%;
text-align: center;
background: #E60537;
}
</style>
效果:
沒有指定網格線的話就是默認1,2,3.....
有幾種寫法:
number
: 可以是一個數字來指代相應編號的網格線,也可使用名稱指代相應命名的網格線span
: 網格項將跨越指定數量的網格軌道span
: 網格項將跨越一些軌道,直到碰到指定命名的網格線- auto: 自動布局, 或者自動跨越, 或者跨越一個默認的軌道
例如:
.item-c {
grid-column: 3 / span 2;//從第3條網格線開始,跨過兩列
grid-row: divname / 5;//從divname開始到第5條網格線
}
2.grid-area屬性
grid-area
屬性指定項目放在哪一個網格區域。
grid-area
屬性還可用作grid-row-start
、grid-column-start
、grid-row-end
、grid-column-end
的合並簡寫形式,直接指定項目的位置。
例如:
.item {
grid-area: <row-start> / <column-start> / <row-end> / <column-end>;
}
這里用法和上面一樣不多解釋。
3.justify-self 屬性, align-self 屬性, place-self 屬性
justify-self
屬性設置單元格內容的水平位置(左中右),跟justify-items
屬性的用法完全一致,但只作用於單個項目。
align-self
屬性設置單元格內容的垂直位置(上中下),跟align-items
屬性的用法完全一致,也是只作用於單個項目。
place-self
屬性是align-self
屬性和justify-self
屬性的合並簡寫形式。
這里比較簡單就演示一個,作用在子元素上,只會影響自己一個元素的排列
.item1{
justify-self: start;
}
到這里我們的網格布局就都介紹完了。
寫在最后
最后再分享一個自己畫的,用網格布局畫一個奧運五環。下一篇貼代碼和思路,覺得還不錯的給小的就一鍵三連吧
🤺🏇🏂🏄♂️🏄♀️🚣🏊
你既然認准一條路,何必去打聽要走多久呢
⛹️🏋️♀️🚴🚴♂️🚵🚵♀️🤸♀️🤼