目錄
- flex彈性布局
- Gird布局
- 開啟網格布局
- 定義網格中的行和列
- 長度值
- 百分比值
- 新單位fr
- 關鍵字
- 函數minmax(min, max)
- 函數-repeat
- auto-fill vs auto-fit
- 舉例說明
- grid-template-areas
- gap
- grid-auto-columns和grid-auto-rows
- justify-content+align-content
- justify-content
- align-content
- justify-items + align-items
- 子元素合并行/列
- 網格線編號系統
- grid-column+ grid-row+grid-area
- 舉例說明·
- 命名網格線
flex彈性布局
flex布局
flex適合一維
布局,在進行二維布局時 => 布局當多行,最后一行數量與前面行數不一致會出現展示問題,如下:
開發者期待的結果是每行展示4個,若是不足4個左對齊。
顯然這種情況需要單獨處理 如最初就判斷元素數量若是%4不為0添加空元素不齊等方式。
但是使用Gird則會輕松解決如上問題。
Gird布局
gird /ɡ??d /(該的 )布局又稱網格布局,是將一個容器劃分為一個個單元格。
開啟網格布局
/* 給父元素設置display: grid | inline-grid;即可開啟網格布局*/
display: grid; /*開啟塊級grid網格布局*/
display:inline-grid; /* 開啟內聯級的網格布局 */
當開啟網格布局之后,以display: grid;為例
-
父元素成為會成為一個
塊級網格容器
,;這意味著它會像普通的塊級元素一樣,獨占一行,寬度若不設置默認會與父元素同寬。 -
子元素被稱為
網格項
,它們已經脫離了常規的文檔流格式上下文,進入了網格格式化上下文;它們的行為由網格布局控制。
舉例說明
<style>.box{width: 800px;min-height: 200px;border: 1px solid #000;/* 開始網格布局 */display: grid;}.box div{background-color: aqua;border-radius: 10px;} </style>
<div class="box"><div>1</div><div>2</div><div>3</div><div>4</div><div>5</div><div>6</div><div>7</div><div>8</div><div>9</div> </div>
如上: 子元素沒有設置寬高 默認填充整個單元格;
通過上述例子可以看到 當開啟網格布局之后
- 默認 列數/列寬:只有1列 該列寬度為父元素寬度 => gird-template-columns: 1fr;
- 默認 行數/行高:行數 = 元素個數 / 列數 有余數+1 / 行高 = 父元素高度/ 行數;
- 默認 子元素寬高:
每個子元素會占據一個網格單元格
, 若是子元素沒有設置寬高則默認與單元格同寬同高
=> align-content: stretch; justify-content: strecth; 修改這兩個屬性后 子元素就會由內容撐開寬高了。
定義網格中的行和列
- 定義網格的行結構 和 列結構
grid-template-columns:定義網格的列結構和每列的寬度;
grid-template-rows:定義網格的行結構和每行的寬度;
其強大之處在于它的屬性值是非常靈活的
這兩個屬性的語法完全相同,只是方向不同,在此使用columns進行展示。
長度值
若是屬性值為長度值,單位可以是px\rem\em等單位
grid-template-columns: 150px 150px 150px 150px;
上述代碼表示將網格分為4列,每列的寬度為150px
grid-template-columns: 200px 100px 300px;
上述代碼表示將網格分為3列,寬度分別為200px 100px 300px;
百分比值
屬性的值也可以是百分比,表示按比例分配父元素的寬度
grid-template-columns: 25% 50% 25%;
上述代碼表示將網格分為3列 第二列的寬度是第一列和第三列的2倍;
新單位fr
使用百分比可以按照比例分配,但是若是列過多需要計算值并且每增加/減少一列都需要重新計算 => 不靈活;
fr
是Grid 布局中獨有
的單位,代表“剩余空間”的等分份額。它解決了百分比和固定值布局不靈活的問題。
grid-template-columns: 1fr 1fr 1fr 1fr;
上述代碼表示將網格列分為4列并且寬度等分。
grid-template-columns: 1fr 2fr 1fr 1fr;
上述代碼表示將網格列分為4列,寬度以1:2:1:1的形式進行展示。
grid-template-columns: 100px 2fr 1fr 1fr;
上述代碼表示將網格分為4列,第一列固定為100px,剩余寬度分給后面的三列,比例為2:1:1
關鍵字
-
auto:由瀏覽器決定寬度。通常會讓內容撐滿剩余空間,類似于 flex: 1
grid-template-columns: 100px 100px auto 100px; // 假設父盒子的寬度為800px 那么就是將網格分為4列 每列的寬度分別是100px 100px 800-100-100-100 = 500px 100px grid-template-columns: 1fr 1fr auto 1fr; // 先按照內容給第三列劃分寬度,剩余寬度平均分給第一、二、四列
-
min-content: 列/行的最小寬度/高度,由該軌道中最小不可斷內容(如一個長單詞或一張圖片)決定。
-
max-content: 列/行的寬度/高度,由該軌道中最大內容(如最長的單詞或最寬的圖片)決定。
函數minmax(min, max)
minmax(min, max): 定義一個尺寸范圍,軌道尺寸將在這個范圍內變化。
min: 最小值
max: 最大值
非常有用,可以創建響應式布局。
函數-repeat
repeat的作用是重復創建具有相同模式的軌道,簡化書寫
repeat(count | auto-fill | auto-fit, track-list)
-
count: 重復次數,如 3。
-
auto-fill / auto-fit: 根據容器寬度自動填充軌道(用于創建響應式布局)。
舉例說明
grid-template-columns: 1fr 1fr 1fr 1fr; /* 簡寫 */grid-template-columns: repeat(4, 1fr);
grid-template-columns: 1fr 1fr auto 1fr;/* 簡寫 */
grid-template-columns: repeat(2, 1fr) auto 1fr;
auto-fill vs auto-fit
/* 盡可能多的創建寬度為200px的列*/
grid-template-columns: repeat(auto-fit, 200px);
auto-fill vs auto-fit: 當軌道數量不足以填滿一行時,auto-fill 會保留空白軌道空間,而 auto-fit 會將空白軌道折疊(將其尺寸壓縮為0),讓非空白軌道擴張以填滿空間
。在大多數響應式布局中,auto-fit 更常用。
讓我們在實際應用場景理解一下這個問題 => 現在想設置寬度為200px的列,至于設置幾行需要根據父元素的寬度來決定(響應式的),此時就可以使用auto-fill/auto-fit來實現
grid-template-columns: repeat(auto-fill, 200px);
grid-template-columns: repeat(auto-fit, 200px);
但是此時發現一個問題,以父元素寬度為700px為例,發現空余部分會被保留,如下:
看起來就比較丑,若是希望多余空白部分被均分,可以進行如下配置
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
minmax(200px, 1fr) 表示列寬最小為200px,最大可以擴展到1fr;
這里要重點關注minmax函數里面的1fr => 1fr 的計算方式:
當容器有剩余空間時,所有設置為 1fr 的軌道會平均分配這些剩余空間
每個 1fr 代表"一份"剩余空間
通過設置父容器的寬度為百分比,再配合auto-fill和minmax(),就能根據屏幕大小自動調整網格的列數,讓布局始終優雅地適應各種設備。
舉例說明
現在將所有元素統一大小寬高均為80px 填充在父元素內, 超過父元素寬度就換行
<style>.box{width: 300px;height: 300px;border: 1px solid #000;/* 開始網格布局 */display: grid;grid-template-columns: repeat(auto-fit, 80px);/* grid-template-rows: repeat(auto-fit, 80px); 這行代碼寫了是沒有意義的 當劃分好列之后,會根據子元素的數量劃分行數 行高會根據行數平分父元素的高度!!!!!*/}.box div{background-color: aqua;color: #fff;border-radius: 2px;}
</style>
</head>
<body><div class="box"><div>1</div><div>1</div><div>1</div><div>1</div><div>1</div><div>1</div><div>1</div><div>1</div><div>1</div></div>
</body>
此時發現子元素之間沒有間隙并且父元素🈶?空白縫隙
- 若是不想保留父元素的空白縫隙 => 子元素平分,可以這樣寫
grid-template-columns: repeat(auto-fit, minmax(80px, 1fr));
- 若是想將元素之間留有空隙,可以使用gap屬性
grid-template-areas
grid-template-areas:網格布局允許指定"區域"(area),一個區域由單個或多個單元格組成。grid-template-areas屬性用于定義區域
gap
控制網格之間的間距有以下幾種屬性
-
column-gap - 控制網格列之間的間距
-
row-gap - 控制網格行之間的間距
-
gap
- 同時設置column-gap和row-gap的簡寫屬性
注意: gap屬性是控制網格之間的間距的 和父元素的間距是沒有設置的,如下:
grid-template-columns: repeat(auto-fit, minmax(80px, 1fr));
gap: 24px;
上述案例在網頁中展示如下:
若是需要父元素和子元素之間設置相同大小,需要給父元素設置padding
padding: 24px;
grid-auto-columns和grid-auto-rows
設定隱藏的網格軌道的大小
justify-content+align-content
justify-content
justify-content 屬性用于**控制整個網格在網格容器內的水平對齊方式 **=> 適用于當網格總寬度小于網格容器寬度
時)
屬性值 | 說明 |
---|---|
start | 網格與網格容器的左端對齊(默認值) |
end | 網格與網格容器的右端對齊 |
center | 網格處于網格容器的X軸的中間 |
stretch | 調整網格項的大小,使其寬度填充整個網格容器 |
space-around | 相當于給每一列單元格添加相同的左右margin |
space-between | 只給單元格內部添加邊距,與父元素之間無邊距 |
space-evenly | 每一列之間的左右間距是相同的 與邊緣也有相同的距離 |
注意點: stretch只在特定情境有效
- [1] 網格總寬度小于容器寬度
- [2] 網格項目`沒有固定寬度或內容尺寸限制
- 網格軌道尺寸使用可拉伸單位(如 fr、auto)
舉例說明
display: grid;
grid-template-columns: repeat(auto-fit, minmax(80px, 1fr));
gap: 24px;
/* justify-content: center; */
像上述例子中,justify-content設置不設置沒有任何意義;
因為repeat(auto-fit, minmax(80px, 1fr))的意思是盡可能多的劃分寬度為80px的列 若是有空白縫隙平分給這些劃分好的列;
所以上述案例中的 網格總寬度 = 網格容器也就是父元素的寬度(而justify-content適用于 網格總寬度< 網格容器也就是父元素的寬度)!
width: 300px;height: 300px;border: 1px solid #000;/* 開始網格布局 */display: grid;grid-template-columns: repeat(2, 50px);gap: 24px;
如上:設置了兩列100px<300px 此時就可以通過justify-content來控制單元格的顯示位置了
justify-content通常與 align-content 一起使用,實現網格在容器中的精確定位。
align-content
align-content 屬性用于控制整個網格在容器內的垂直對齊方式(當網格總寬度小于容器寬度時)
屬性值 | 說明 |
---|---|
start | 網格與網格容器的上端對齊 |
end | 網格與網格容器的下端對齊 |
center | 網格處于網格容器的Y軸的中間 |
stretch | 調整網格項的大小,使其高度填充整個網格容器 (默認值) |
space-around | 相當于給每一列單元格添加相同的上下margin |
space-between | 只給單元格內部添加邊距,與父元素之間無邊距 |
space-evenly | 每一列之間的上下間距是相同的 與邊緣也有相同的距離 |
這里就解釋了為什么沒有給子元素設置高度但是子元素依舊能夠填充整個單元格的原因了 => align-content的默認屬性值為stretch
若是修改該屬性值,子元素的高度就是由內容來撐開了,如下
若是還是想要在不設置高度的情況下進行拉伸可以使用 align-items(子元素的屬性)進行控制
justify-items + align-items
justify-content 與 align-content是控制網格在網格容器中的對齊方式
而 justify-items 與 align-items是控制內容在單元格中的對齊方式。
子元素合并行/列
網格線編號系統
網格線從1開始編號,從左到右(列),從上到下(行)
一個6列的網格有7條垂直線
一個4行的網格有5條水平線
grid-column+ grid-row+grid-area
語法:
grid-column : [start] / [end] - 從start網線開始到end網線結束 控制列占據
grid-row: [start] / [end] - 從start網線開始到end網線結束 控制行占據
也可以使用span
關鍵子進行簡寫以列為例
gird-column: start / span num - 從start網線開始 跨越num列
若是該元素同時跨域行和列 也可以使用gird-area
簡寫
gird-area: [row-start] / [column-start] / [row-end] / [column-end]
舉例說明·
<style>.box{width: 300px;height: 300px;border: 1px solid #000;/* 開始網格布局 */display: grid;grid-template-columns: repeat(auto-fit, minmax(80px, 1fr));gap: 24px;}.box div{background-color: aqua;color: #fff;}.haveTwo{grid-column: 2 / 4; /* 這表示該元素將在第2條網線開始到第4條網線結束占據2列*/grid-row: 1 / span 2 ;}
</style>
<body><div class="box"><div>1</div><div class="haveTwo">2</div><div>3</div><div>4</div><div>5</div><div>6</div><div>7</div><div>8</div><div>9</div></div>
</body>
當然上述案例可以直接使用grid-area結果是相同的,如下
grid-area: 1 / 2 / 3 / 4 ;
命名網格線
在定義軌道的同時,還可以給網格線命名以提高代碼可讀性,使用方括號定義名稱,如 [main-start]
.container {grid-template-columns: [sidebar-start] 200px [sidebar-end content-start] 1fr [content-end];/* 創建了兩條列軌道。產生了四條垂直的網格線,它們被命名為:1. sidebar-start2. sidebar-end (同時也是 content-start)3. content-end*/
}
若是使用auto-fit,應該如何命名網格線呢? 這完全不用擔心,gird內置自動索引
功能,如下
grid-template-columns: repeat(auto-fit, [col-start] minmax(80px, 1fr) [col-end]);/*創建n條軌道產生了n+2條垂直網線 它們被命名為第一列:col-start 1 和 col-end 1第二列:col-start 2 和 col-end 2第三列:col-start 3 和 col-end 3以此類推...*/
上述示例中 為網格線命名以及使用網格線和并列代碼修改如下
grid-template-columns: repeat(auto-fit, [col-start] minmax(80px, 1fr) [col-end]);
grid-column: col-start 2 / col-end 3;