一、核心術語
- 容器
設定了 "display: gird / inline-grid" 的元素,就稱之為網格容器(grid container)
- 專案(Item)
grid 容器中的直接子元素就為網格專案(grid item)
下面的 .container 元素就為網格容器(grid container),所有的直接子元素 .item 就為該網格容器的一個個專案(grid item)
<div class="container"> <div class="item"></div> <div class="item"> <p class="sub-item"></p> </div> <div class="item"></div> </div>
- 行和列
容器裡面的水平區域稱為 "行"(row),垂直區域稱為 "列"(column)
- 單元格(cell)
行和列的交叉區域
- 網格線(grid line)
劃分網格的線段,水平線劃分出行,垂直線劃分出列
二、網格容器相關屬性
2.1 大小及名稱
grid-template-rows和grid-template-columns 用於定義將網格劃分為多少行、多少列;每行/每列的名稱,每行的高度、每列的寬度.
.container { display: grid; /* 定義網格佈局 */ grid-template-rows: 100px 100px 100px; /* 定義三行,每行的高度為100 */ grid-template-columns: 100px 100px 100px; /* 定義三列,每列寬度為100 */ } .item { width: 100%; height: 100%; display: flex; justify-content: center; align-items: center; border: 1px solid white; background-color: orange; color: white; } <body> <span>H</span> <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 class="item">7</div> <div class="item">8</div> <div class="item">9</div> </div> <span>H</span> </body>
2.1.1 行或列的大小
px|repeat()|fr|minmax()|fit-content()|min-content|max-content|auto|%
2.1.1.1 repeat()
當有重複值時,可以使用repeat()
函式進行書寫簡化
repeat(數量|auto-fill|auto-fit,px|fr|min-content|max-content|auto|minmax|fit-content):
/*透過 repeat 函式來簡化上面的寫法*/ .container { display: grid; grid-template-rows: repeat(3, 100px); grid-template-columns: repeat(3, 100px); }
- repeat:auto-fll
當大小是固定的,但是容器的大小不確定,希望由瀏覽器自動劃分行數或列數時,可使用該屬性
.container { display: grid; grid-template-columns: repeat(auto-fill, 100px); /* 具體多少列根據容器大小自動劃分(每列列寬 100px) */ grid-template-rows: repeat(3, 100px); }
- repeat:auto-fit
該關鍵字與上面的 auto-fill 的行為基本是相同的,都會盡可能的生成更多的行或列,但是單元格中沒有元素時,會將對應的列寬收縮為 0
- auto-fill vs auto-fit
auto-fill 不管單元格是否中是否有元素,都會生產對應單元格的空間
auto-fit 則是如果單元格中沒有元素,會將對應的列寬收縮為 0
2.1.1.2 fr
fr是fraction 的縮寫,意為"片段",該單位可以更方便的定義單元格之間的比例關係
2.1.1.2 minax()
minmax() : 該函式可以生成一個長度範圍,表示長度在這個範圍之中
minmax(px|fr|%|min-content|max-content|auto,px|fr|%|min-content|max-content|auto)
2.1.1.3 auto
該關鍵字表示長度由瀏覽器進行決定(也可以理解為預設會自動吸收對應容器的剩餘長度,當然如果對應單元格元素設定了 min-width/max-width
當達到對應的最值時,對應的效果可能就會有些出入)
2.1.1.4 自動計算值的優先順序
優先順序: - minmax > fr > auto
tip: - 為了保證最小空間,網格可能會超出容器元素的範圍(auto 的最小寬度為 fit-content,即內容寬度)
2.1.2 為隱式建立的行、列指定大小
grid-auto-rows / grid-auto-columns: 用於指定一些自動生成的行和列,對應的行高與列寬。不指定這兩個屬性時對應的行高或列寬是
fit-content(
適應內容的)
什麼時候會隱式建立行、列?
如: 當一個網格是三行三列的,但裡面某一個網格專案指定在第 5 行等等,此時網格就會自動生成一些行或列 →
或在一個三行三列的網格中只有 9 個單元格,但網格中的元素卻超出了九個時,此時也會自動生成一行或列
如下示例:
在一個三行三列的網格容器中,有十個子元素 → 因為網格單元格不夠,就會自動生成一行,我們可以透過 grid-auto-row 屬性來指定對應自動生成行的行高(列同理)
.container { gap: 6px; display: grid; grid-template-columns: repeat(3, 100px); grid-template-rows: repeat(3, 100px); grid-auto-rows: 100px; /* 指定自動生成的行的行高大小 */ }
2.1.3 網格線名稱
grid-template-columns 屬性和 grid-template-rows 屬性裡面,還可以使用方括號,指定每一根網格線的名字,後面網格專案(item)中的grid-row / grid-column屬性可以使用對應的網格線名稱,可以更加方便將專案元素佈局到對應想要的位置上。
網格佈局允許同一根線有多個名字,比如[fifth-line row-5]
。
.container { display: grid; grid-template-columns: [col-1] 100px [col-2] auto [col-3] 100px [col-4]; grid-template-rows: [row-1] 100px [row-2] 100px [row-3] 100px [row-4]; }
2.2 網格之間的間隙
row-gap設定行之間的間隔(行間距),column-gap設定列間距,gap是行間距和列間距的縮寫
/*普通寫法*/ { row-gap: 設定行與行之間的間隔(行間距); column-gap: 設定列與列之間的間隔(列間距); } /*我們也可以上面兩個屬性的簡寫屬性 gap 來快速設定對應的間隔*/ { gap: 行間距 列間距; } /*當行間距與列間距相同時,我們也可以只需寫一個值*/ { gap: 行列間距; }
2.3 網格專案的放置順序
grid-auto-flow用於設定專案的放置順序。預設的放置順序是"先行後列",即先填滿第一行,再開始放入第二行。值通常為 row(先行後列) 或 column(先列後行),預設為 row 即先行後列 → 基本效果如下示例圖
屬性除了可以設定成 row
和 column
,還可以設定成 row dense
和 column dense
,第二個值主要用於某些專案在指定完位置後,剩下的專案怎麼放置(如: 先行後列,並且儘可能緊密填滿) →
文字描述可能會比較抽象,我們可以透過下面幾張圖來進行理解
2.4 對網格進行分割槽
網格佈局允許指定"區域"(area),一個區域由單個或多個單元格組成。
grid-template-areas
屬性用於定義區域。該屬性定義的分割槽名,在專案中使用grid-area屬性進行引用
.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'; }
上面程式碼先劃分出9個單元格,然後將其定名為a
到i
的九個區域,分別對應這九個單元格。
多個單元格合併成一個區域的寫法如下。
grid-template-areas: 'a a a' 'b b b' 'c c c';
如果某些區域不需要利用或不屬於任何區域,則使用"點"(.
)表示。
grid-template-areas: 'a . c' 'd . f' 'g . i';
- 注意,區域的命名會影響到網格線。每個區域的起始網格線,會自動命名為
區域名-start
,終止網格線自動命名為區域名-end
。 - 比如,區域名為
header
,則起始位置的水平網格線和垂直網格線叫做header-start
,終止位置的水平網格線和垂直網格線叫做header-end
。
2.5 設定容器內整個網格的對齊
justify-content
屬性是整個內容區域在容器裡面的水平位置
align-content
屬性是整個內容區域的垂直位置(上中下)place-content: 上面兩者合併的簡寫
justify-content: start | end | center | stretch | space-around | space-between | space-evenly;
align-content: start | end | center | stretch | space-around | space-between | space-evenly;
place-content: <align-content> <justify-content> /*如果省略第二個值,瀏覽器就會假定第二個值等於第一個值。*/
+ 對應屬性值的作用(及對應 justify-content 示例圖):
- start - 對齊容器的起始邊框(預設)
- end - 對齊容器的結束邊框
- center - 容器內部居中
- stretch - 專案大小沒有指定時,拉伸佔據整個網格容器(即沒有透過 grid-template-columns / grid-template-rows 指定對應列寬或行高時)
- space-around - 每個專案兩側的間隔相等。所以,專案之間的間隔比專案與容器邊框的間隔大一倍
- space-between - 專案與專案的間隔相等,專案與容器邊框之間沒有間隔(兩端對齊)
- space-evenly - 專案與專案的間隔相等,專案與容器邊框之間也是同樣長度的間隔
2.6 設定單元格內的元素對齊方式
justify-items
屬性設定單元格內容的水平位置(左中右)
align-items
屬性設定單元格內容的垂直位置(上中下)。place-items 屬性是兩個屬性合併的簡寫
justify-items: start | end | center | stretch;
align-items: start | end | center | stretch;
place-items: <align-items> [justify-items]; /* 簡寫: 如果只寫一個值時,將會認為這兩個值相等 */對應屬性值的作用(及對應 justify-items 示例圖):
- start - 對齊單元格的起始邊緣
- end - 對齊單元格的結束邊緣
- center - 單元格內部居中
- stretch - 拉伸,佔滿單元格的整個寬度(預設值) → 當元素沒有指定具體的大小時
.container { justify-items: start; /*水平方向,內容左對齊*/ }
.container { align-items: start; /*垂直方向頂對齊*/ }
三、網格專案(item)相關屬性
3.1設定專案的起始位置
grid-column-start
屬性:左邊框所在的垂直網格線
grid-column-end
屬性:右邊框所在的垂直網格線
grid-row-start
屬性:上邊框所在的水平網格線
grid-row-end
屬性:下邊框所在的水平網格線
grid-column: <grid-column-start> / <grid-column-end>
grid-row: <grid-row-start> / <grid-row-end
>
.item-1 { grid-column-start: 2; grid-column-end: 4; }
上面程式碼指定,1號專案的左邊框是第二根垂直網格線,右邊框是第四根垂直網格線。由於沒有指定上下邊框,所以會採用預設位置,即上邊框是第一根水平網格線,下邊框是第二根水平網格線。除了1號專案以外,其他專案都沒有指定位置,由瀏覽器自動佈局,這時它們的位置由容器的grid-auto-flow
屬性決定,這個屬性的預設值是row
,因此會"先行後列"進行排列。
下面的例子是指定四個邊框位置的效果。
.item-1 { grid-column-start: 1; grid-column-end: 3; grid-row-start: 2; grid-row-end: 4; }
這四個屬性的值,除了指定為第幾個網格線,還可以指定為網格線的名字。
.item-1 { grid-column-start: header-start; grid-column-end: header-end; }
這四個屬性的值還可以使用span
關鍵字,表示"跨越",即左右邊框(上下邊框)之間跨越多少個網格。
.item-1 { grid-column-start: span 2; /*與grid-column-end: span 2效果是一樣的*/ }
上面程式碼表示,1號專案的左邊框距離右邊框跨越2個網格。
3.2 為專案設定區域
grid-area
屬性指定專案放在哪一個區域。
grid-area
: 使用grid-template-areas定義的區域名稱 |
<row-start> / <column-start> / <row-end> / <column-end>
.item-1 { grid-area: e; }
上面程式碼中,1號專案位於e
區域,效果如下圖。
grid-area
屬性還可用作grid-row-start
、grid-column-start
、grid-row-end
、grid-column-end
的合併簡寫形式,直接指定專案的位置。
下面是一個例子。
.item-1 { grid-area: 1 / 1 / 3 / 3; }
3.3 專案內容重疊處理
因為元素的大小可以跟單元格的大小無關,即元素可以指定比單元格更大的大小,所以就有可能會超出到其它的單元格上,導致與其它單元格元素產生了層疊。
z-index: 該屬性來指定對應的層疊順序
order: 屬性規定了專案的順序,值越小越佈局順序越靠前,未指定則相當於為0(因此總是顯示在有order值的項前面,例如下圖中的3-6).
3.4設定某個單元格內容的對齊
當需要統一設定所有單元格內容對齊時可以使用 2.6 中的justify-items、aligin-items兩個屬性。如果想單獨設定某個單元格內容的對齊,需要使用下面的屬性
justify-self
屬性設定單元格內容的水平位置(左中右),跟justify-items
屬性的用法完全一致,但只作用於單個專案。
align-self
屬性設定單元格內容的垂直位置(上中下),跟align-items
屬性的用法完全一致,也是隻作用於單個專案。
place-self
屬性是align-self
屬性和justify-self
屬性的合併簡寫形式。
justify-self: start | end | center | stretch
align-self: start | end | center | stretch
place-self: <align-self> [justify-self]; 如果省略第2個值,則認為與第1個值相等
- start - 對齊單元格的起始邊緣
- end - 對齊單元格的結束邊緣
- center - 單元格內部居中
- stretch - 拉伸,佔滿單元格的整個寬度(預設值) → 當元素沒有指定具體的大小時
下面是justify-self: start
的例子。
.item-a { justify-self: start; }
四、參考及整理
現今 CSS3 最強二維佈局系統 Grid 網格佈局_css3 grid-CSDN部落格
CSS Grid 網格佈局教程 - 阮一峰的網路日誌 (ruanyifeng.com)
grid - CSS:層疊樣式表 | MDN (mozilla.org)