唐山做網(wǎng)站建設(shè)公司搜索引擎數(shù)據(jù)庫
深入學(xué)習(xí) CSS3 目前最強(qiáng)大的布局系統(tǒng) Grid 網(wǎng)格布局
Grid 網(wǎng)格布局的基本認(rèn)識
Grid 網(wǎng)格布局: Grid 布局是一個基于網(wǎng)格的二位布局系統(tǒng),是目前 CSS 最強(qiáng)的布局系統(tǒng),它可以同時對列和行進(jìn)行處理(它將網(wǎng)頁劃分成一個個網(wǎng)格,可以任意組合不同的網(wǎng)格,做出各種各樣的布局)
CSS 布局的過渡: CSS 一直用于對頁面進(jìn)行布局,但一直都不是很完美
-
1.一開始我們使用 table 做布局,然后轉(zhuǎn)向浮動、定位以及 inline-block,但所有這些方法本質(zhì)上都是 Hack 的方式,并且遺漏了很多重要的功能(例如垂直居中)
-
"Hack" 通常指的是一種快速、非標(biāo)準(zhǔn)或非預(yù)期的解決方案,用于繞過某些限制或問題
-
-
2. 隨著 CSS3 的引入,特別是 Flexbox 和 Grid 布局的出現(xiàn),網(wǎng)頁布局變得更加直觀和靈活,減少了對這些 “Hack” 方法的依賴,Flexbox 和 Grid 提供了更強(qiáng)大的布局控制,解決了許多歷史遺留的布局問題,如垂直居中、響應(yīng)式設(shè)計等
-
3. Flexbox 在一定程度上解決了這些問題,但它的目的是為了更簡單的一維布局,而不是復(fù)雜的二維布局
-
4. Flexbox 布局是軸線布局,只能指定 "項目" 針對軸線的位置,可以看作是一維布局 → 而 Grid 布局則是將容器劃分成 "行" 和 "列",產(chǎn)生單元格,然后指定 "項目所在" 的單元格,可以看作是二維布局(Grid 布局遠(yuǎn)比 Flex 布局強(qiáng)大)
-
5. Grid 布局是第一個專門為解決布局問題而生的 CSS 模塊
術(shù)語: 在深入了解網(wǎng)格的概念之前,我們需要了解一些重要的術(shù)語
-
1. 網(wǎng)格容器與項目
-
容器(Container): 設(shè)置了 "display: gird / inline-grid" 的元素,就稱之為網(wǎng)格容器(grid container)
-
項目(Item): grid 容器中的直接子元素就為網(wǎng)格項目(grid item)
-
.container {display: gird }
-
+ 下面的 .container 元素就為網(wǎng)格容器(grid container),所有的直接子元素 .item 就為該網(wǎng)格容器的一個個項目(grid item) <div class="container"><div class="item"></div> <div class="item"><p class="sub-item"></p></div><div class="item"></div> </div>
-
-
-
2. 行和列: 容器里面的水平區(qū)域稱為 "行"(row),垂直區(qū)域稱為 "列"(column)
-
3. 單元格: 行和列的交叉區(qū)域,稱為 "單元格"(cell)
-
4. 網(wǎng)格線: 劃分網(wǎng)格的線,稱為"網(wǎng)格線"(grid line),水平網(wǎng)格線劃分出行,垂直網(wǎng)格線劃分出列
Grid 網(wǎng)格布局的使用
Grid 網(wǎng)格布局的屬性主要分為兩類: 一類定義在容器上面,稱為容器屬性,另一類定義在項目上面,稱為項目屬性
容器屬性
display: 將元素定義為 grid contaienr,并為其內(nèi)容建立新的網(wǎng)格格式化上下文(grid formatting context)
-
grid
- 生成一個塊級 (block-level) 網(wǎng)格 -
inline-grid
- 生成一個行級 (inline-level) 網(wǎng)格 -
subgrid
- 如果你的 grid container 本身就是一個 grid item(即,嵌套網(wǎng)格),你可以使用這個屬性來表示你想從它的父節(jié)點獲取它的行/列的大小,而不是指定它自己的大小 -
.container {display: grid | inline-grid | subgrid; }
-
tip: 注意:column
,float
,clear
, 以及vertical-align 對一個 grid container 沒有影響(即設(shè)置這些屬性了也無效)
grid-template-columns / grid-template-rows: 劃分行和列,使用空格來分隔的多個值來定義網(wǎng)格的列和行
-
grid-template-columns:
- 屬性定義每一列的列寬 -
grid-template-rows:
- 屬性定義每一行的行高 -
.container {display: grid; /* 定義網(wǎng)格布局 */grid-template-rows: 100px 100px 100px; /* 定義每一行行高 */grid-template-columns: 100px 100px 100px; /* 定義每一列列寬 */ }+ 上面代碼指定了一個三行三列的網(wǎng)格,列寬和行高都為 100px.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>
-
-
repeat(count,any-value):
- 有時候,重復(fù)寫同樣的值非常麻煩,尤其網(wǎng)格很多時 → 這時,可以使用repeat()
函數(shù),簡化重復(fù)的值-
+ 通過 repeat 函數(shù)來簡化上面的寫法 .container {display: grid;grid-template-rows: repeat(3, 100px);grid-template-columns: repeat(3, 100px); }
-
-
auto-fill 關(guān)鍵字:
- 有時,單元格的大小是固定的,但是容器的大小不確定 → 如果希望每一行(或每一列)容納盡可能多的單元格,這時可以使用 “auto-fill” 關(guān)鍵字表示自動填-
.container {display: grid;grid-template-columns: repeat(auto-fill, 100px); /* 具體多少列根據(jù)容器大小自動劃分(每列列寬 100px) */grid-template-rows: repeat(3, 100px); }+ 下圖列數(shù)只是某一容器大小的示例圖,并非所有,具體列數(shù)根據(jù)對應(yīng)的容器大小與列寬有關(guān)
-
-
-
auto-fit 關(guān)鍵字:
- 該關(guān)鍵字與上面的 auto-fill 的行為基本是相同的,都會盡可能的生成更多的列或行,但是兩者也存在一點區(qū)別-
auto-fill 不管單元格是否中是否有元素,都會生產(chǎn)對應(yīng)單元格的空間
-
auto-fit 則是如果單元格中沒有元素時,會將對應(yīng)的列寬收縮為 0
-
上面文字描述起來可能比較抽象,如下兩圖示例(為了更好的展示對應(yīng)的區(qū)別,先將上面單元格的數(shù)量縮減成 3 個先)
-
-
-
🔺可以理解為 auto-fill 會盡可能的沾滿容器空間,所以可能會存在一些空單元格 → 而 auto-fit 不會因為容器還有剩余寬度而進(jìn)行生成更多的單元格,而是會收縮網(wǎng)格(只生成對應(yīng)有內(nèi)容的單元格 - 🔺常用)
-
-
fr 關(guān)鍵字:
- 網(wǎng)格布局提供了fr
關(guān)鍵字(fraction 的縮寫,意為"片段"),該關(guān)鍵字可以更方便的定義單元格之間的比例關(guān)系-
如下三列寬分別為
1fr 2fr 3fr
時,就表示第二項是第一項的兩倍,第三項就是第一項的三倍 -
-
-
-
minmax(min,max):
- 該函數(shù)可以生成一個長度范圍,表示長度在這個范圍之中- 如
minmax(300px, 1fr)
就表示列寬不小于300px
,不大于1fr
- 如
-
auto 關(guān)鍵字:
- 該關(guān)鍵字表示長度由瀏覽器進(jìn)行決定(也可以理解為默認(rèn)會自動吸收對應(yīng)容器的剩余長度,當(dāng)然如果對應(yīng)單元格元素設(shè)置了min-width/max-width
當(dāng)達(dá)到對應(yīng)的最值時,對應(yīng)的效果可能就會有些出入) -
auto / fr / minmax:
- 該三個對應(yīng)的功能都比較類似,都會自動吸收容器的剩余空間,但如果同時存在時也會有對應(yīng)的優(yōu)先級與對應(yīng)需要注意的問題優(yōu)先級:
-minmax 優(yōu)先級大于 fr,fr 的優(yōu)先級
tip:
-為了保證最小空間,網(wǎng)格可能會超出容器元素的范圍(auto 的最小寬度為 fit-content,即內(nèi)容寬度)
-
網(wǎng)格線的名稱:
-grid-template-columns
屬性和grid-template-rows
屬性里面,還可以使用方括號,指定每一根網(wǎng)格線的名字,后面網(wǎng)格項目(item)可以使用對應(yīng)的網(wǎng)格線名稱,可以更加方便將項目元素布局到對應(yīng)想要的位置上(網(wǎng)格項目中具體如何使用,后面網(wǎng)格項目屬性講到時再進(jìn)行演示)-
.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]; }
-
-
gap / row-gap / column-gap : 用來設(shè)置行與行之間的間隔(行間距),與列與列的間隔(列間距)
-
+ 普通寫法{row-gap: 設(shè)置行與行之間的間隔(行間距); column-gap: 設(shè)置列與列之間的間隔(列間距); }+ 我們也可以上面兩個屬性的簡寫屬性 gap 來快速設(shè)置對應(yīng)的間隔: gap: row-gap column-gap{gap: 行間距 列間距;}+ 當(dāng)行間距與列間距相同時,我們也可以只需寫一個值{gap: 行列間距;}
-
.container {...row-gap: 12px; /* 設(shè)置行間距 */column-gap: 12px; /* 設(shè)置列間距 */ }
-
grid-auto-flow: 用于指定網(wǎng)格中項目的放置流向(放置順序),值通常為 row
(先行后列) 或 column
(先列后行),默認(rèn)為 row
即先行后列 →
基本效果如下示例圖
-
-
grid-auto-flow
屬性除了可以設(shè)置成row
和column
,還可以設(shè)置成row dense
和column dence
,第二個值主要用于某些項目在指定完位置后,剩下的項目怎么放置(如: 先行后列,并且盡可能緊密填滿)→
文字描述可能會比較抽象,我們可以通過下面幾張圖來進(jìn)行理解 -
grid-template-areas: 網(wǎng)格布局中允許通過該屬性來指定一些區(qū)域(area),每一個區(qū)域由一個或多個單元格組成
-
{grid-template-columns: repeat(3, 100px);grid-template-rows: repeat(3, 100px);grid-template-areas:"a b c""d e f""g h i"; } + 例1: 如上述代碼就相當(dāng)于給網(wǎng)格劃分出 9 個單元格,人后然后將其定名為 a-i 的九個區(qū)域,分別對應(yīng)這九個單元格
-
{grid-template-areas: 'a a a''b b b''c c c'; } + 例2: 上面代碼將 9 個單元格分成 a、b、c 三個區(qū)域
-
{grid-template-areas: 'a . c''d . f''g . i'; } + 例3: 如果某些區(qū)域不需要利用,則使用 "點"(.)表示
-
grid-template-areas: "header header header""main main sidebar""footer footer footer"; + 🔺例4: 上面代碼中,頂部是頁眉區(qū)域 header,底部是頁腳區(qū)域 footer,中間部分則為 main 和 sidebar
-
作用:
- 當(dāng)在網(wǎng)格容器中劃分好對應(yīng)的區(qū)域后,我們可以在子元素(網(wǎng)格項目)中通過grid-area
屬性,來對某一個網(wǎng)格項目快速的放置到對應(yīng)的區(qū)域中(具體圖例演示,在后面項目屬性grid-area
中進(jìn)行更加直觀的示例) -
tip:
-需要注意區(qū)域的命名會影響到網(wǎng)格線,每個區(qū)域的起始網(wǎng)格線會自動命名為 "區(qū)域名-start",終止網(wǎng)格線會自動命名為 "區(qū)域名-end"
place-items / justify-items / align-items: 這些屬性用于設(shè)置單元格中元素的擺放位置,justify-items
水平方向,align-items
垂直方向,place-items
前面兩個的簡寫方式
-
+ 屬性值: 左 中 右 拉伸 .container {justify-items: start | end | center | stretch;align-items: start | end | center | stretch;place-items: <align-items> <justify-items>; /* 簡寫: 如果只寫一個值時,將會認(rèn)為這兩個值相等 */ }+ 對應(yīng)屬性值的作用(及對應(yīng) justify-items 示例圖):- start - 對齊單元格的起始邊緣- end - 對齊單元格的結(jié)束邊緣- center - 單元格內(nèi)部居中- stretch - 拉伸,占滿單元格的整個寬度(默認(rèn)值) → 當(dāng)元素沒有指定具體的大小時
-
place-content / justify-content / align-content: 這些屬性用于定義整個網(wǎng)格區(qū)域在容器元素的擺放位置,justify-content
水平方向,align-content
垂直方向,place-content
前面兩個的簡寫方式
-
+ 屬性值: 這些屬性值跟 flex 布局中的基本一致 .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; place-content: <align-content> <justify-content>; /* 簡寫: 如果只寫一個值時,將會認(rèn)為這兩個值相等 */ }+ 對應(yīng)屬性值的作用(及對應(yīng) justify-content 示例圖):- start - 對齊容器的起始邊框(默認(rèn))- end - 對齊容器的結(jié)束邊框- center - 容器內(nèi)部居中- stretch - 項目大小沒有指定時,拉伸占據(jù)整個網(wǎng)格容器(即沒有通過 grid-template-columns / grid-template-rows 指定對應(yīng)列寬或行高時)- space-around - 每個項目兩側(cè)的間隔相等。所以,項目之間的間隔比項目與容器邊框的間隔大一倍- space-between - 項目與項目的間隔相等,項目與容器邊框之間沒有間隔(兩端對齊)- space-evenly - 項目與項目的間隔相等,項目與容器邊框之間也是同樣長度的間隔
-
grid-auto-rows / grid-auto-columns: 用于指定一些自動生成的行和列,對應(yīng)的行高與列寬(如: 當(dāng)一個網(wǎng)格是三行三列的,但里面某一個網(wǎng)格項目指定在第 5 行等等,此時網(wǎng)格就會自動生成一些行或列 →
或在一個三行三列的網(wǎng)格中只有 9 個單元格,但網(wǎng)格中的元素卻超出了九個時,此時也會自動生成一行或列)→
這些自動生成的行或列,對應(yīng)的行高或列寬是 fit-content
適應(yīng)內(nèi)容的 →
而該兩個屬性就是用來指定一些自動生成的行或列對應(yīng)的行高與列寬的
-
如下示例:
在一個三行三列的網(wǎng)格容器中,有十個子元素 → 因為網(wǎng)格單元格不夠,就會自動生成一行,我們可以通過 grid-auto-row 屬性來指定對應(yīng)自動生成行的行高(列同理)
-
.container {gap: 6px;display: grid;grid-template-columns: repeat(3, 100px);grid-template-rows: repeat(3, 100px);grid-auto-rows: 100px; /* 指定自動生成的行的行高大小 */ }
-
-
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
這六個屬性的簡寫形式 - tip: - 從易讀易寫的角度考慮,還是建議不要合并屬性,所以這里就不詳細(xì)介紹這兩個屬性了
項目屬性
grid-row-start / grid-row-end / grid-column-start / grid-column-end :
-
(1)用于定義某個網(wǎng)格項目的的位置,通過指定項目的四個邊框,分別定位在哪根網(wǎng)格線上
-
+ 如下: 將第一個網(wǎng)格項目的網(wǎng)格項的行和列都在對應(yīng)行或列的 1 到 3 網(wǎng)格線上 .item1 {grid-row-start: 1; /* 定義項目行開始線 */grid-row-end: 3; /* 定義項目行結(jié)束線 */grid-column-start: 1; /* 定義項目列開始線 */grid-column-end: 3; /* 定義項目列結(jié)束線 */ }
-
-
-
(2)這四個屬性的值,除了指定為第幾個網(wǎng)格線,還可以指定為網(wǎng)格線的名字
-
.container {width: 400px;display: grid;gap: 6px;/* 給網(wǎng)格容器對應(yīng)的網(wǎng)格線命名 */grid-template-columns: [column-1] 100px [column-2] 100px [column-3] 100px;grid-template-rows: [row-1] 100px [row-2] 100px [row-3] 100px; }/* 通過命名網(wǎng)格線來指定 item1 對應(yīng)的放置位置 */ .item1 {grid-row-start: row-1;grid-row-end: row-3;grid-column-start: column-1;grid-column-end: column-3; }
-
-
-
(3)在該四個屬性上也可以使用 span 關(guān)鍵字 來表示跨越多少個網(wǎng)格(↓)
-
{grid-row-start: span 所要跨越的網(wǎng)格個數(shù);grid-column-start: span 3; /* 如: 表示該項目在列上跨越 3 個單元格 */ }
-
-
grid-row / grid-column: 該兩個屬性為上面 grid-row-start / grid-row-end / grid-column-start / grid-column-end
屬性的簡寫形式
-
.item {grid-column: <start-line> / <end-line>;grid-row: <start-line> / <end-line>; }+ 該兩個屬性只是上面的簡寫形式,所以具體就不做過多的演示了
grid-area: 屬性用于指定項目放在哪一個區(qū)域,來快速放置對應(yīng)項目到指定的位置上(具體網(wǎng)格區(qū)域的定義方式,參照前面)
我們可以通過在網(wǎng)格容器上定義好對應(yīng)的區(qū)域,在在對應(yīng)的網(wǎng)格項目上通過該屬性來指定項目所要放置的位置,從而實現(xiàn)快速的實現(xiàn)想要的布局效果,如下
↓
place-self / justify-self / align-self: 這些屬性用于設(shè)置單元格內(nèi)容的擺放位置,justify-self
水平方向,align-self
垂直方向,place-self
前面兩個的簡寫方式
-
tip: 該三個屬性與前面容器屬性中 place-items / justify-items / align-items 的作用一樣,不同的容器屬性設(shè)置會作用在所有的單元格上,而該項目屬性(slef)只作用于某個項目上(單元格)
-
.item {justify-self: start | end | center | stretch;align-self: start | end | center | stretch; } + 因為前面容器屬性 justify-items 上已經(jīng)解釋了每個屬性值的含義了,所以這里就不再過多的解釋每一個屬性值了
-
其它屬性補(bǔ)充
-
z-index: 如果單元格中的元素與其它單元格元素出現(xiàn)層疊是,可以通過該屬性來指定對應(yīng)的層疊順序(與 position 層疊同理)
例如: 因為元素的大小可以跟單元格的大小無關(guān),即元素可以指定比單元格更大的大小,所以就有可能會超出到其它的單元格上 → 與其它單元格元素產(chǎn)生了層疊
-
order: 屬性規(guī)定了彈性容器中的可伸縮項目在布局時的順序(
flexbox
),該屬性再網(wǎng)格布局中同樣適用,值越小越布局順序越靠前(如下示例圖)