你需要的Grid布局入門教程


一、Grid布局概述

首先,Grid 布局與 Flex布局 有一定的相似性,都可以指定容器內部多個項目的位置。但是,Grid 布局遠比 Flex 布局強大!

  • Flex 布局是軸線布局,只能指定"項目"針對軸線的位置,可以看作是一維布局
  • Grid 布局則是將容器划分成"行"和"列",產生單元格,然后指定"項目所在"的單元格,可以看作是二維布局

 

二、基本概念

(1)容器和項目

采用網格布局的區域,稱為"容器"(container)。容器內部采用網格定位的子元素,稱為"項目"(item)。

<div class="container">
  <div class="item"><p>1</p></div>
  <div class="item"><p>2</p></div>
  <div class="item"><p>3</p></div>
</div>

上述代碼中,如果.container設置了display:grid屬性,則它就是網格布局容器 ,其內部孩子節點.item就稱為項目

注意:項目只能是容器的頂層子元素,不包含項目的子元素,所以p元素不是項目。Grid 布局只對項目生效

 

(2)行和列

容器里面的水平區域稱為"行"(row),垂直區域稱為"列"(column),行和列的交叉區域,稱為"單元格"(cell)

(3)網格線

划分網格的線,稱為"網格線"(grid line)。水平網格線划分出行,垂直網格線划分出列。

這就是一個4行4列的網格,存在5根水平網格線和5根垂直網格線

 

三、容器屬性

定義在容器上面的屬性,稱為容器屬性

(1)display

  • display: grid指定一個容器采用塊級網格布局
<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title></title>
        <style type="text/css">
            .container{    
                display: grid;
                grid-template-columns: 50px 50px; 
                grid-template-rows: 50px 50px; 
                border: 3px solid #9575CD;
            }
            .item {
              font-size: 2em;
              text-align: center;
              border: 1px solid #e5e4e9;
            }
            .item-1 {
              background-color: #aaaaff;
            }
            
            .item-2 {
              background-color: #1bf6d5;
            }
            
            .item-3 {
              background-color: #56a982;
            }
            
            .item-4 {
              background-color: #6072c2;
            }
        </style>
    </head>
    <body>
<span>輔助元素1</span>
<div class="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>
<span>輔助元素2</span>
    </body>
</html>

  • display: inline-grid指定一個容器采用行內網格布局
.container{    
    display: inline-grid;
    grid-template-columns: 50px 50px; 
    grid-template-rows: 50px 50px; 
    border: 3px solid #9575CD;
}

特別注意:設為網格布局以后,容器子元素(項目)的floatdisplay: inline-blockdisplay: table-cellvertical-aligncolumn-*等設置都將失效。

.item {
  font-size: 2em;
  text-align: center;
  border: 1px solid #e5e4e9;
  float: right; /* 設置所有項目右浮動(失效) */
}

從結果可以看出,子項目並沒有右浮動到最右邊(失效)

 

(2)grid-template-columns 和 grid-template-rows

grid-template-columns 屬性定義每一列的列寬

grid-template-rows 屬性定義每一行的行高

  • 使用絕對單位划分
.container{    
    display: grid;
    grid-template-columns: 50px 50px; /* 定義兩列,列寬為50px */
    grid-template-rows: 50px 50px; /* 定義兩行,行高為50px */
    border: 3px solid #9575CD;
}

 

  • 使用百分比划分
.container{    
    display: grid;
    grid-template-columns: 20% 10%; /* 定義兩列,列寬為20% 10% */
    grid-template-rows: 40% 30%; /* 定義兩行,行高為40% 30% */
    border: 3px solid #9575CD;
}

 

  • repeat()函數

從上面例子可以看出,存在重復寫同樣的值,如果網格很多會顯得十分臃腫,這時可以使用reapeat()函數來優化

.container{    
    display: grid;
    grid-template-columns: repeat(2,150px);
    grid-template-rows: repeat(2,50px);
}

reapeat()函數接收兩個值,第一個值為重復次數,第二個值為需要重復的值。另外,重復某種模式也是可以的:

.container{    
    display: grid;
    grid-template-columns: repeat(2,150px 50px);
}

repeat(2,150px 50px):表示重復了模式,定義了4列,第一列和第三列為150px ,第二列和第四列為50px

 

  • auto-fill 關鍵字

auto-fill值用於自動填充,當單元格的大小需要固定不變,容器大小不確定時使用

.container{    
    display: grid;
    grid-template-columns: repeat(auto-fill,50px);
}

repeat(auto-fill,50px):表示設置每列寬度為50px自動填充,直到容器不能放置更多的列,然后換行排列(例子如下):

.container{    
    display: grid;
    width: 150px;
    border: 1px dashed red;
    grid-template-columns: repeat(auto-fill,50px);
}

(換行排列)

 

  • fr 關鍵字

fr關鍵字用於表示比例關系(fraction 的縮寫,意為"片段”)

.container{    
    display: grid;
    grid-template-columns: 1fr 5fr;
}

1fr 5fr:表示設置兩列,列寬分別為1fr5fr ,第二列是第一列的5倍

另外,fr可以與絕對長度的單位結合使用:

.container{    
    display: grid;
    grid-template-columns:50px 1fr 2fr;
}

50px 1fr 2fr:表示第一列寬度為50px,第二列寬度時第三列的一半

 

  • auto 關鍵字

auto關鍵字表示由瀏覽器決定自己的長度

.container{    
    display: grid;
    grid-template-columns: 50px auto 50px auto;
}

50px auto 50px auto表示第二列和第四列自動填充,相當於flex:1 

 

(3)row-gap 和 column-gap

row-gap屬性設置 行與行 的間隔(行間距)

column-gap屬性設置 列與列 的間隔(列間距)

.container{    
    display: grid;
    grid-template-columns: 50px 50px;
    grid-template-rows: 50px 50px;
    row-gap: 20px; /* 行間距為20px */
    column-gap: 10px; /* 列間距為10px */
}

另外,這兩個屬性有個復合屬性:gap

gap語法:

gap: <row-gap> <column-gap>;
.container{    
    row-gap: 20px; 
    column-gap: 10px;
    /* 等同於 */
    gap: 20px 10px;
}

注意:如果gap只有一個值,默認第二個值等於第一個值

普及:這三個屬性名原來是由前綴grid-的,目前最新標准已經將grid-前綴刪除,但還是可以用~

 

(4)grid-auto-flow

 划分網格后,容器中的子元素默認按照“先行后列”的順序自動放置在每一個網格中(先填滿第一行,在開始第二行)

grid-auto-flow屬性自己規定排列順序,默認值為 row,可以設置 column,類似於 flex-direction 
.container{    
    display: grid;
    grid-template-columns: 50px 50px;
    grid-template-rows: 50px 50px;
    grid-auto-flow: row; /* 默認值 */
}

.container{    
    display: grid;
    grid-template-columns: 50px 50px;
    grid-template-rows: 50px 50px;
    grid-auto-flow: column; /* 先列后行 */
}

 

(5)justify-items 和 align-items

justify-items屬性設置單元格內容水平位置(左中右)

align-items屬性設置單元格內容垂直位置(上中下)

語法:

.container {
  justify-items: start | end | center | stretch;
  align-items: start | end | center | stretch;
}

你沒有看錯,這兩個屬性的屬性值完全相同,都可以去這幾個值:

  • start:對齊單元格的起始邊緣。
  • end:對齊單元格的結束邊緣。
  • center:單元格內部居中。
  • stretch:拉伸,占滿單元格的整個寬度(默認值)。

start:單元格的內容頭部對齊:

.container{    
    display: grid;
    width: 200px;
    border: 1px dashed red;
    grid-template-columns: 100px 100px;
    grid-template-rows: 100px 100px;
    justify-items: start;
}

效果如圖:

 

 end:單元格的內容尾部對齊:

.container{    
    display: grid;
    width: 200px;
    border: 1px dashed red;
    grid-template-columns: 100px 100px;
    grid-template-rows: 100px 100px;
    justify-items: end; /* 對齊單元格的結束邊緣 */
}

效果如圖:

 

center:單元格內部居中

.container{    
    display: grid;
    width: 200px;
    border: 1px dashed red;
    grid-template-columns: 100px 100px;
    grid-template-rows: 100px 100px;
    justify-items: center; /* 單元格內部居中 */
}

效果如圖:

 

stretch:占據單元格整個寬度(拉伸):

.container{    
    display: grid;
    width: 200px;
    border: 1px dashed red;
    grid-template-columns: 100px 100px;
    grid-template-rows: 100px 100px;
    justify-items: stretch; /* 默認值-拉伸占據整個寬度 */
}

效果如圖:

這里只演示下justify-items 屬性,對應單元格的左中右,相信大家也有點感覺了,align-items 取值是一樣的,對應的是單元格的上中下部分,這里就不再演示了,感興趣的小伙伴自行嘗試喲

 

同樣,這兩個屬性也有復合屬性place-items

語法:

place-items: <align-items> <justify-items>;

第一個值為單元格內容垂直位置,第二個值為單元格水平位置

.container{    
    display: grid;
    width: 200px;
    border: 1px dashed red;
    grid-template-columns: 100px 100px;
    grid-template-rows: 100px 100px;
    place-items: center center; /* 單元格內容水平垂直居中 */
}

效果如圖:

注意:如果省略第二個值,則默認與第一個值相等

 

(6)justify-content 和 align-content

justify-content屬性是整個內容區域在容器里面的水平位置(左中右)

align-content屬性是整個內容區域的垂直位置(上中下)

注意區分justify-items 和 align-items屬性,一個是內容相對於單元格位置,一個是整個內容區域相對於父容器位置!!!

語法:

.container {
  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 - 對齊容器的結束邊框。

  • center - 容器內部居中。

  • stretch - 項目大小沒有指定時,拉伸占據整個網格容器。

  • space-around - 每個項目兩側的間隔相等。所以,項目之間的間隔比項目與容器邊框的間隔大一倍。

  • space-between - 項目與項目的間隔相等,項目與容器邊框之間沒有間隔。

  • space-evenly - 項目與項目的間隔相等,項目與容器邊框之間也是同樣長度的間隔。

同樣,這里我也只演示justify-content屬性,align-content 屬性完全一致,只是方向不同,感興趣的小伙伴自行嘗試下啦~~

start:對齊容器的起始邊框。

.container{    
    display: grid;
    width: 300px;
    border: 1px dashed red;
    grid-template-columns: 100px 100px;
    grid-template-rows: 100px 100px;
    justify-content: start;/* 對齊容器的起始邊框(默認) */
}

 

end:對齊容器的結束邊框。

.container{
    justify-content: end;/* 對齊容器的結束邊框 */
}

 

center:容器內部居中。

.container{
    justify-content: center;/* 容器內部居中 */
}

 

space-around:每個項目兩側的間隔相等。項目之間的間隔比項目與容器邊框的間隔大一倍。

.container{
    justify-content: space-around;/* 每個項目兩側的間隔相等。項目之間的間隔比項目與容器邊框的間隔大一倍 */
}

 

space-between:項目與項目的間隔相等,項目與容器邊框之間沒有間隔。

.container{
    justify-content: space-between;/* 項目與項目的間隔相等,項目與容器邊框之間沒有間隔。 */
}

 

space-evenly:項目與項目的間隔相等,項目與容器邊框之間也是同樣長度的間隔。

.container{
    justify-content: space-evenly;/* 項目與項目的間隔相等,項目與容器邊框之間也是同樣長度的間隔。 */
}

 

相信大家看完這幾個屬性值后,學過 Flex布局 的小伙伴肯定再熟悉不過了,在flex布局中項目與容器對齊方式也類似這幾種

同樣滴,這兩個屬性也是有復合屬性的:place-content

語法:

place-content: <align-content> <justify-content>

第一個值整個內容相對容器的垂直位置,第二個值整個內容相對容器的水平位置

.container{    
    display: grid;
    width: 300px;
    height: 300px;
    border: 1px dashed red;
    grid-template-columns: 100px 100px;
    grid-template-rows: 100px 100px;
    place-content: center center; /* 整體內容水平垂直居中 */
}

效果如圖:

注意:如果省略第二個值,則默認與第一個值相等

 

四、項目屬性

注意:項目屬性需要定義在項目上才能生效!

(1)grid-column-start、grid-column-end、grid-row-start、grid-row-end

這四個屬性是用於指定某個項目的位置,根據項目的四個邊框來定位在哪根兒網格線

  • grid-column-start 屬性:左邊框所在的垂直網格線

  • grid-column-end 屬性:右邊框所在的垂直網格線

  • grid-row-start 屬性:上邊框所在的水平網格線

  • grid-row-end 屬性:下邊框所在的水平網格線

下面所演示的代碼片段也是基於前面的例子:

.container{    
    display: grid;
    width: 300px;
    height: 300px;
    border: 1px dashed red;
    grid-template-columns: 100px 100px;
    grid-template-rows: 100px 100px;
}
.item-1 {
    grid-column-start: 2;/* 開始於第二根網格線 */
    grid-column-end: 4;/* 結束於第四根網格線 */
    background-color: #aaaaff;
}

效果如圖:

 

只有項目一指定了具體,其他項目自動布局,為了便於觀察,再定位一次:

.item-1 {
    grid-column-start: 2;/* 垂直第一根 */
    grid-column-end: 4; /* 垂直第四根 */
    grid-row-start: 1;/* 水平第一根 */
    grid-row-end: 3;/* 水平第三根 */
    background-color: #aaaaff;
}

效果如下:

這四個屬性值還可以使用span關鍵字,表示“跨越”,就像table表格的單元格合並colspan和rowspan

.item-1 {
    grid-column-start: span 2;/* 橫跨兩個網格線 */
    /* 等同於 */
    grid-column-end: span 2;/* 橫跨兩個網格線 */
    background-color: #aaaaff;
}

效果如圖:

這個結果相信有些小伙伴會說其他子元素為什么沒有在第一個子元素之后繼續排列?

我想說的是grid-template-columns: 100px 100px; 我只設置了兩列,如果改成grid-template-columns: 100px 100px 100px; 這樣,那容器剩余的空間就可以補齊啦~

注意:使用這四個屬性,如果產生了項目的重疊,則使用z-index屬性指定項目的重疊順序

 

(2)grid-column 和 grid-row 

grid-column:grid-column-startgrid-column-end的合並簡寫形式

grid-row:grid-row-start屬性和grid-row-end的合並簡寫形式

語法:

.item {
  grid-column: <start-line> / <end-line>;
  grid-row: <start-line> / <end-line>;
}

來個栗子:

.item-1 {
    grid-column: 1 / 3; /* 占據水平方向上的第1根和第3根 */
    grid-row: 2 / 4; /* 占據垂直方向上的第2根和第4根 */
    background-color: #aaaaff;
}

效果如圖:

 注意:斜杠以及后面的部分可以省略,默認跨越一個網格

 

(3)justify-self 和 align-self

justify-self屬性設置單元格內容的水平位置(左中右),跟justify-items屬性的用法完全一致,但只作用於單個項目。

align-self屬性設置單元格內容的垂直位置(上中下),跟align-items屬性的用法完全一致,也是只作用於單個項目。

語法:

.item {
  justify-self: start | end | center | stretch;
  align-self: start | end | center | stretch;
}

取值:

  • start:對齊單元格的起始邊緣。

  • end:對齊單元格的結束邊緣。

  • center:單元格內部居中。

  • stretch:拉伸,占滿單元格的整個寬度(默認值)

.item-1 {
    justify-self: start; /* 指定項目單元格左對齊 */
    background-color: #aaaaff;
}

這里我就演示一個就行了,其他都一樣,有手就行,大家可以自行嘗試下

 

place-self屬性是align-self屬性和justify-self屬性的合並簡寫形式

語法:

place-self: <align-self> <justify-self>;

例子:

.item-1 {
    place-self: center center;
    background-color: #aaaaff;
}

 

打賞

免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2021 CODEPRJ.COM