網(wǎng)格布局Grid

前面我們講到了一種非常方便的布局方式flex,也提到了他是一種非常方便的一維布局解決方案,那么二維呢?我們有Grid。
作為一個二維布局,它遠(yuǎn)比flex來的強(qiáng)大。

什么是Grid

Grid布局,也就是我們所謂的網(wǎng)格布局,它可以輕松實現(xiàn)容器內(nèi)子元素的任意位置布局(將我們的外部容器分為一個個的網(wǎng)格,然后在任意一個網(wǎng)格內(nèi)放入我們想要放入的子元素),他比flex強(qiáng)大很多,但可惜的是,他在部分瀏覽器中的支持并沒有flex那么普及,所以在考慮到兼容性的情況下,我們可能很少會去采用這一種布局的方式,但是這并不影響我們學(xué)習(xí)他。(對于某些項目來說,可能只需要支持某一個特定的瀏覽器,這個時候,Grid布局就會有很大的用武之地)和flex一樣,想要把一個容器設(shè)置為grid容器也非常的簡單,只需要講他的display屬性設(shè)置為grid。

.box{
    display: grid | inline-grid;
}

容器的屬性

網(wǎng)格示例

在了解容器的屬性之前,我們首先需要了解以下在網(wǎng)格布局中非常重要的兩個概念,行(row)和列(column)。在上面這幅圖中,有橫豎總共8條表格線,將一個容器分為了3行和3列,在我們的網(wǎng)格布局中,屬性往往是兩兩出現(xiàn),分別對應(yīng)行和列,因此我們可以根據(jù)作用是否相同將他們進(jìn)行一個分組。

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

1.grid-template-columns和grid-template-rows

grid-template-columns:用于定義每一列的列寬
grid-template-rows:用于定義每一行的行高
對于這兩個屬性我們可以有很多種方式的值。

(1)直接使用px值

比如我們要實現(xiàn)一個上面這幅圖所展示的表格我們可以這樣來寫(假設(shè)每一個單元格的寬高都是100px):

.box{
    display: grid;
    grid-template-columns: 100px 100px 100px;
    grid-template-rows: 100px 100px 100px;
}
(2)使用百分比

如果box的寬高已經(jīng)固定為300px,我們還可以使用百分比來實現(xiàn)上面的內(nèi)容

.box{
    display: grid;
    grid-template-columns: 33.3% 33.3% 33.3%;
    grid-template-rows: 33.3% 33.3% 33.3%;
}
(3)fr關(guān)鍵字

grid提供了一個關(guān)鍵字fr(片段,fraction的縮寫),他代表一個比例關(guān)系,所以上面這段代碼我們又可以改成這樣:

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

這代表了1:1:1的關(guān)系。如果1fr 2fr 3fr,則代表了1:2:3的關(guān)系。還有一點(diǎn)值得注意的是,fr還可以和px值配合使用,比如grid-template-columns: 100px 1fr 1fr,代表第一列為100px,剩下兩列為1:1的關(guān)系。

(4)repeat函數(shù)

我們還可以用repeat函數(shù)來寫上面這個方法,他支持兩個參數(shù),第一個參數(shù)是重復(fù)的次數(shù),第二個參數(shù)是需要重復(fù)的值。
.box{
display:grid;
grid-template-columns: repeat(3, 1fr); /* 這里的1fr當(dāng)然也可以是100px或者33.3% */
grid-template-rows: repeat(3, 1fr);
}
第二個參數(shù)還可以傳遞某種組合,比如這樣grid-template-columns: repeat(2,100px 200px),這樣就會生成一共四列,其中第一第三列為100px,第二第四列為200px。

(5)auto-fill關(guān)鍵字

這是配合repeat函數(shù)使用的一個關(guān)鍵字,可以在父元素寬高不固定的時候使用。grid-template-columns: repeat(auto-fill, 100px),這段代碼表示用寬度100px的列來填充容器,知道填充不下為止。

(6)auto關(guān)鍵字

自適應(yīng),grid-template-columns: 100px auto,比如這一段代碼,代表了第一列的寬度為100px,第二列寬度自適應(yīng),會自動填充滿容器的寬度。(當(dāng)然也會有特殊情況比如單元格有min-width)

(7)minmax函數(shù)

產(chǎn)生一個長度范圍,接受兩個參數(shù),分別為最小值和最大值,比如這樣一段代碼:grid-template-columns: 1fr minmax(100px, 1fr),代表第二列的寬度大于100px,且小于1fr。

(8)網(wǎng)格線的名稱

我們可以給網(wǎng)格線來設(shè)置名稱,比如這樣:grid-template-columns: [c1] 100px [c2] auto [c3 end-line],我們可以看到同一根先還可以有不同的名字。

2.grid-row-gap、grid-column-gap和grid-gap

grid-row-gap:用于設(shè)置行與行之間的間距(行間距)
grid-column-gap:用于設(shè)置列與列之間的間距(列間距)
grid-gap:上面兩個值的合并寫法,語法grid-gap: <grid-row-gap> <grid-column-gap>,當(dāng)然他也可以值傳遞一個參數(shù),代表第二個值和第一個值相等。
按照最新的標(biāo)準(zhǔn)這三個屬性的grid前綴可以省略,分別寫成row-gap,column-gapgap

3.grid-template-areas

用于給單元格進(jìn)行命名,可以是一個單元格代表一個區(qū)域,也可以是多個單元格代表一個區(qū)域:

.box{
    display: grid;
    grid-template-columns: 100px 100px 100px;
    grid-template-rows: 100px 100px 100px;
    grid-template-areas:'a b c'
                                     'd e f'
                                     'g g g';
}

區(qū)域命名還會直接影響到網(wǎng)格線的名稱區(qū)域名-start,區(qū)域名-end

4.grid-auto-flow

可以是row、column、row densecolumn dense四個值中的其中一個,表示子元素的排列規(guī)則,其中row表示先行后列,column表示先列后行。而dense表示盡可能填滿,不出現(xiàn)空格,假設(shè)我們有a,b,c三個元素,寬度都為50%,然后我們將a,b元素上下排列,然后如果使用row排序,c元素灰出現(xiàn)在b元素的后面,但是如果我們使用row dense排序,c的位置就來到了a的后面,如下例:

<style>
  .box{
    display: grid;
    grid-template-columns: 100px 100px;
    grid-template-rows: 100px 100px;
  }
  .item {
    font-size: 4em;
    text-align: center;
    border: 1px solid #e5e4e9;
   }
  .item-1 {
    background-color: red;
    grid-column-start: 1;
    grid-column-end: 2;  
  }
  .item-2 {
    background-color: green;
    grid-column-start: 1;
    grid-column-end: 2; 
  }
  .item-3 {
    background-color: yellow;
  }
</style>
<div class="box">
  <div class="item item-1">a</div>
  <div class="item item-2">b</div>
  <div class="item item-3">c</div>
</div>

效果如下圖:

默認(rèn):grid-auto-flow: row

現(xiàn)在我們給box中加上grid-auto-flow: row dense;效果變成了這樣。
grid-auto-flow: row dense

5. justify-items、align-items和place-items

justify-items:設(shè)置單元格內(nèi)容的水平位置(左中右)
align-items:設(shè)置單元格內(nèi)容的垂直位置(上中下)
他們都可以有以下四個值:

  • stretch:拉伸,占滿單元格的整個寬度(默認(rèn)值)
  • start:對齊單元格的起始邊緣
  • end:對齊單元格的結(jié)束邊緣
  • center:單元格內(nèi)部居中
.box{
  justify-items: start | end | center | stretch;
  align-items: start | end | center | stretch;
}

place-items是以上兩個值的合并簡寫:

place-items: <align-items> <justify-items> /* 如果兩個值相等則可以省略第二個值。*/

6.justify-content、align-content和place-content

主要作用于網(wǎng)格的內(nèi)容區(qū)域沒有完全填滿容器的情況下。
justify-content:整個內(nèi)容區(qū)域在容器里面的水平位置(左中右),
align-content:整個內(nèi)容區(qū)域的垂直位置(上中下)。

.box{
  justify-content: start | end | center | stretch | space-around | space-between | space-evenly;
  align-content: start | end | center | stretch | space-around | space-between | space-evenly;  
}
  • start:對齊容器的起始邊框
  • end:對齊容器的結(jié)束邊框
  • center:容器內(nèi)部居中
  • stretch:項目大小沒有指定時,拉伸占據(jù)整個網(wǎng)格容器
  • space-around:每個項目兩側(cè)的間隔相等。所以,項目之間的間隔比項目與容器邊框的間隔大一倍
  • space-between:項目與項目的間隔相等,項目與容器邊框之間沒有間隔
  • space-evenly:項目與項目的間隔相等,項目與容器邊框之間也是同樣長度的間隔
    place-content是align-content和justify-content的合并簡寫形式。
    place-content: <align-content> <justify-content> /* 如果兩個值相等則可以省略第二個值。*/

7.grid-auto-columns和grid-auto-rows

當(dāng)一些項目所在的位置超出我們現(xiàn)有網(wǎng)格的時候,可以用這兩個屬性來規(guī)定自動生成的網(wǎng)格的寬高。

8.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的合并簡寫形式。

項目的屬性

接下來我們來看項目上可以使用哪些屬性,我們依舊是分組來看:

  • grid-column-start、grid-column-end、grid-row-start和grid-row-end
  • grid-column和grid-row
  • grid-area
  • z-index
  • justify-self、align-self和place-self

1.grid-column-start、grid-column-end、grid-row-start和grid-row-end

這四個屬性用于指定項目的具體位置:
grid-column-start屬性:左邊框所在的垂直網(wǎng)格線
grid-column-end屬性:右邊框所在的垂直網(wǎng)格線
grid-row-start屬性:上邊框所在的水平網(wǎng)格線
grid-row-end屬性:下邊框所在的水平網(wǎng)格線
這里我們注意看前面第一幅圖中的標(biāo)線,我們?nèi)绻褑卧穹旁诘谝桓竦奈恢茫蔷鸵旁谒骄W(wǎng)線1,和水平網(wǎng)格線2的中間。(垂直同理)
這里除了直接使用網(wǎng)格的數(shù)字之外,我們還可以使用網(wǎng)格線的名稱。(就是上文定義的,這里派上了用場)
不僅如此,這里還有一個span關(guān)鍵字,代表左右邊框之間跨越了幾個網(wǎng)格。grid-column-start: span 2grid-column-end: span 2的效果完全一致,有了這個寫法,我們可以來固定一條邊,然后通過跨越幾個單元格的方式來計算出另外一條邊的位置。

2.grid-column和grid-row

上面四個屬性的合并縮寫模式,值得一提的是,這里中間要用/號進(jìn)行分隔。

.item {
  grid-column: 1 / 2;
  grid-row: 1 / 2;
}
/* 等同于 */
.item {
  grid-column-start: 1;
  grid-column-end: 2;
  grid-row-start: 1;
  grid-row-end: 2;
}

值得注意的是,斜杠后面的數(shù)字是可以省略的,默認(rèn)為一個網(wǎng)格。

3.grid-area

用于指定項目放在哪一個區(qū)域,我們可以直接這樣寫:

item {
    grid-area: a;
}

這樣item就被放到了上面定義的a區(qū)域里面,不僅如此,他還可以看做grid-row-start、grid-column-start、grid-row-end、grid-column-end的合并簡寫,直接指定項目位置。

grid-area: <row-start> / <column-start> / <row-end> / <column-end>

4.z-index

上面說了那么多的位置放置屬性,那么肯定會導(dǎo)致位置重疊的問題,我們使用z-index來控制重疊的順序。

5.justify-self、align-self和place-self

justify-self:設(shè)置單元格內(nèi)容的水平位置(跟justify-items屬性的用法一致,但只作用于單個項目)
align-self:設(shè)置單元格內(nèi)容的垂直位置(跟align-items屬性的用法一致,也是只作用于單個項目)

.item {
  justify-self: stretch | start | end | center;
  align-self: stretch | start | end | center;
}
  • stretch:拉伸,占滿單元格的整個寬度(默認(rèn)值)
  • start:對齊單元格的起始邊緣
  • end:對齊單元格的結(jié)束邊緣
  • center:單元格內(nèi)部居中
    place-self是align-self和justify-self的合并簡寫形式。
    place-self: <align-self> <justify-self>  /* 如果兩個值相等則可以省略第二個值。*/
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容