原文 https://mp.weixin.qq.com/s/aHyWCzUYwcnkwt5MWhGfFw
相信很多前端同志對彈性盒(Flex)布局很熟悉,但是對于網格(Grid)布局很陌生,甚至在項目中從來沒有用到過。今天就帶大家學習一下網格布局是如何玩的。
> 如果你懶的動手寫代碼,或者本地創建項目,博主貼心的為你準備了代碼預覽地址,你可以一邊調試一邊預覽效果。
## 1\. 什么是網格布局
網格是由一系列水平及垂直的線構成的一種布局模式。根據網格,我們能夠將設計元素進行排列,幫助我們設計一系列具有固定位置以及寬度的元素的頁面,使我們的網站頁面更加統一。
一個網格通常具有許多的**列(column)與行(row)**,以及行與行、列與列之間的間隙,這個間隙一般被稱為**溝槽(gutter)**。
也就是下面這張圖:

我們一般會根據我們的設計圖來決定網格的布局長什么樣子。
接下來我們從一個基礎的網格系統開始學起來。
## 2\. 自定義網格布局
布局如下:
~~~
<h1>Simple?grid?example</h1>
<div?class="container">
??<div>One</div>
??<div>Two</div>
??<div>Three</div>
??<div>Four</div>
??<div>Five</div>
??<div>Six</div>
??<div>Seven</div>
</div>
~~~
### 2.1. Gird
首先,你要設置網格布局,必須把display設置為`grid`。
~~~
.container?{
??display:?grid;
}
~~~
### 2.2. grid-template-columns
此時的布局并沒有任何變化,我們需要通過`grid-template-columns`設置列的寬度,給個三列,每列200px吧。
~~~
.container?{
??display:?grid;
??grid-template-columns:?200px?200px?200px;
}
~~~
此時,頁面效果如下:

### 2.3. gap
使用 grid-column-gap(en-US) 屬性來定義列間隙;使用 grid-row-gap(en-US) 來定義行間隙;使用 grid-gap(en-US) 可以同時設定兩者。
修改代碼:
~~~
.container?{
??display:?grid;
??grid-template-columns:?200px?200px?200px;
??grid-gap:?20px;
??gap:?20px;
}
~~~
**備注:**gap屬性曾經有一個grid-前綴,不過后來的標準進行了修改,目的是讓他們能夠在不同的布局方法中都能起作用。盡管現在這個前綴不會影響語義,但為了代碼的健壯性,你可以把兩個屬性都寫上。
此時,頁面效果如下:

### 2.4. fr
這里除了使用px意外,我們也可以用 fr 這個單位來靈活地定義網格的行與列的大小。這個單位代表網格容器中可用空間的一份。也就是把列等分以后,每列占據的份數是多少,fr值越法,占據的空間就越大。
修改代碼:
~~~
.container?{
??display:?grid;
??grid-template-columns:?1fr?1fr?1fr;
}
~~~
這個意思是,把列三等分,每列占據1份空間。
此時,頁面效果如下:

### 2.5. repeat
你可以使用repeat來重復構建具有某些寬度配置的某些列。舉個例子,如果要創建多個等寬軌道,可以用下面的方法。
~~~
.container?{
??display:?grid;
??grid-template-columns:?repeat(3,?1fr);
??grid-gap:?20px;
}
~~~
這個效果跟上面的代碼是一致的。第一個傳入 repeat 函數的值(3)表明了后續列寬的配置要重復多少次,而第二個值(1fr)表示需要重復的構建配置,這個配置可以具有多個長度設定。例如repeat(2, 2fr 1fr),如果你仍然不明白,可以實際測試一下效果,這相當于填入了 2fr 1fr 2fr 1fr。
### 2.6. grid-template-rows
通過`grid-template-rows`可以設置行的高度,我們給每行設置個100px吧。
~~~
.container?{
??display:?grid;
??grid-gap:?20px;
??grid-template-columns:?1fr?1fr?1fr;
??grid-template-rows:?100px?100px?100px;
}
~~~
此時,頁面效果如下:

### 2.7. minmax() 函數
100 像素高的軌道有時可能會不夠用,因為時常會有比 100 像素高的內容加進去。所以,我們可以將其設定為至少 100 像素,并且能夠跟隨內容來自動拓展尺寸,從而保證能容納所有內容。顯而易見,你很難知道網頁上某個元素的尺寸在不同情況下會變成多少,一些額外的內容或者更大的字號就會導致許多能做到像素級精準的設計出現問題。所以有了minmax()函數。
minmax()函數為一個行/列的尺寸設置了取值范圍。比如設定為 minmax(100px, auto),那么尺寸就至少為 100 像素,并且如果內容尺寸大于 100 像素則會根據內容自動調整。在這里試一下把 grid-auto-rows 屬性設置為minmax函數。
~~~
.container?{
??display:?grid;
??grid-gap:?20px;
??grid-template-columns:?1fr?1fr?1fr;
??grid-template-rows:?minmax(100px,?auto)?100px?100px;
}
~~~
此時,頁面效果如下:

可以看到,我們設置了minmax(100px, auto)以后,此時內容高度會自動撐高。
### 2.8. auto-fill
在上面的布局中,每次都是把行和列的屬性重復寫三次才能都生效。有沒有更簡便的方法呢?有,那就是repeat中的一個參數:auto-fill。
~~~
.container?{
??display:?grid;
??grid-gap:?20px;
??grid-template-columns:?repeat(auto-fill,?minmax(200px,?1fr));
??grid-auto-rows:?minmax(100px,?auto);
}
~~~
此時,頁面效果如下:

以上代碼參考地址:https://stackblitz.com/edit/web-platform-vabj4w?file=styles.css
## 3\. 基于線的元素放置
既然是一個網格,那么它就有線,我們可以根據這些線所處的位置來放置我們的元素。如下圖所示:

在英文中,第一條列分隔線(即網格邊緣線)在網格的最左邊而第一條行分隔線在網格的最上面。而對于阿拉伯語,第一條列分隔線在網格的最右邊,因為阿拉伯文是從右往左書寫的。
### 3.1. grid-column和grid-row
我們根據這些分隔線來放置元素,通過以下屬性來指定從那條線開始到哪條線結束。
* grid-column-start
* grid-column-end
* grid-row-start
* grid-row-end
這些屬性的值均為分隔線序號,你也可以用以下縮寫形式來同時指定開始與結束的線。
* grid-column
* grid-row
注意開始與結束的線的序號要使用/符號分開。
上面的概念聽起來是不是沒聽懂?沒關系,我們接下來做個博客系統的布局,你就懂了:

頁面布局如下:
~~~
<div?class="container">
??<header>This?is?my?lovely?blog</header>
??<aside>
????<h2>Other?things</h2>
????<p>
??????Nam?vulputate?diam?nec?tempor?bibendum.?Donec?luctus?augue?eget
??????malesuada?ultrices.?Phasellus?turpis?est,?posuere?sit?amet?dapibus?ut,
??????facilisis?sed?est.
????</p>
??</aside>
??<article>
????<h1>My?article</h1>
????<p>
??????Duis?felis?orci,?pulvinar?id?metus?ut,?rutrum?luctus?orci.?Cras
??????porttitor?imperdiet?nunc,?at?ultricies?tellus?laoreet?sit?amet.?Sed
??????auctor?cursus?massa?at?porta.?Integer?ligula?ipsum,?tristique?sit?amet
??????orci?vel,?viverra?egestas?ligula.?Curabitur?vehicula?tellus?neque,?ac
??????ornare?ex?malesuada?et.?In?vitae?convallis?lacus.?Aliquam?erat
??????volutpat.?Suspendisse?ac?imperdiet?turpis.?Aenean?finibus?sollicitudin
??????eros?pharetra?congue.?Duis?ornare?egestas?augue?ut?luctus.?Proin
??????blandit?quam?nec?lacus?varius?commodo?et?a?urna.?Ut?id?ornare?felis,
??????eget?fermentum?sapien.
????</p>
????<p>
??????Nam?vulputate?diam?nec?tempor?bibendum.?Donec?luctus?augue?eget
??????malesuada?ultrices.?Phasellus?turpis?est,?posuere?sit?amet?dapibus?ut,
??????facilisis?sed?est.?Nam?id?risus?quis?ante?semper?consectetur?eget
??????aliquam?lorem.?Vivamus?tristique?elit?dolor,?sed?pretium?metus
??????suscipit?vel.?Mauris?ultricies?lectus?sed?lobortis?finibus.?Vivamus?eu
??????urna?eget?velit?cursus?viverra?quis?vestibulum?sem.?Aliquam?tincidunt
??????eget?purus?in?interdum.?Cum?sociis?natoque?penatibus?et?magnis?dis
??????parturient?montes,?nascetur?ridiculus?mus.
????</p>
??</article>
??<footer>Contact?me@mysite.com</footer>
</div>
~~~
添加css樣式
~~~
body?{
??width:?90%;
??max-width:?900px;
??margin:?2em?auto;
??font:?0.9em/1.2?Arial,?Helvetica,?sans-serif;
}
header,
footer?{
??border-radius:?5px;
??padding:?10px;
??background-color:?rgb(207,?232,?220);
??border:?2px?solid?rgb(79,?185,?227);
}
aside?{
??border-right:?1px?solid?#999;
}
.container?{
??display:?grid;
??grid-template-columns:?1fr?3fr;
??gap:?20px;
}
header?{
??grid-column:?1?/?3;
??grid-row:?1;
}
article?{
??grid-column:?2;
??grid-row:?2;
}
aside?{
??grid-column:?1;
??grid-row:?2;
}
footer?{
??grid-column:?1?/?3;
??grid-row:?3;
}
~~~
我們再來看看這個頁面布局的網格線:

拿header來說,grid-column: 1 / 3,意思就是說從列的位置從分隔線序號1開始,從分隔線序號3結束,是不是跟上面圖中的網格線一致?其他元素的布局也是類似的,你可以一一的對照去看。
以上代碼參考地址:https://stackblitz.com/edit/web-platform-tmtmba?file=styles.css
### 3.2. grid-template-areas
當然,上面的布局實現方式可以用另一種往網格放元素的方式:grid-template-areas,并且你要命名一些元素并在屬性中使用這些名字作為一個區域。
將之前基于線的元素放置代碼刪除(或者重新下載一份新的文件),然后加入以下 CSS 規則:
~~~
.container?{
??display:?grid;
??grid-template-areas:
????"header?header"
????"sidebar?content"
????"footer?footer";
??grid-template-columns:?1fr?3fr;
??gap:?20px;
}
header?{
??grid-area:?header;
}
article?{
??grid-area:?content;
}
aside?{
??grid-area:?sidebar;
}
footer?{
??grid-area:?footer;
}
~~~
同樣的也能實現上面博客的布局效果。
## 4\. 網格排版框架
網格排版框架一般由 12 到 16 列的網格構成,下面我們實現一個12列網格的排版框架。頁面布局還是以上面博客的為例,參考代碼:https://stackblitz.com/edit/web-platform-pfi7ju?file=styles.css
我們可以用基于線的元素放置模式來將我們的內容放到這個 12 列的網格中。
~~~
.container?{
??display:?grid;
??grid-template-columns:?repeat(12,?minmax(0,?1fr));?/**?關鍵代碼?**/
??gap:?20px;
}
header?{
??grid-column:?1?/?13;
??grid-row:?1;
}
article?{
??grid-column:?4?/?13;
??grid-row:?2;
}
aside?{
??grid-column:?1?/?4;
??grid-row:?2;
}
footer?{
??grid-column:?1?/?13;
??grid-row:?3;
}
~~~
在Google瀏覽器中使用開發者工具查看它的網格線,你應該能看到這 12 列的網格是如何工作的了。

> 總結:我們在這篇文章中接觸了 CSS 網格版面的主要特性,你現在應該可以在你自己的設計中使用了。
最后,看完了別忘了給博主三連。請轉發給你的朋友,讓他們也學會網格布局的使用技巧吧,非常感謝!
- 后端
- composer
- composer配置國內鏡像
- composer安裝及設置2
- PHP
- 貝塔SG11加密
- 申請KEY
- 開始加密
- php 中連接tcp服務的三種方式
- php websocket 教程
- editor內容轉換數組
- 使用正則判斷中文維吾爾文
- PHP常用函數總結
- 常用助手函數
- 通過Imagick把pdf轉換圖片
- 維吾爾語基本區轉換擴展區
- php GD庫生成一個由文字和圖片生成新的圖片
- aes加密
- php數組函數 -- array_column,array_multisort 實現二維數組排序
- PHP操作Excel
- php更新內容
- 輔助查詢(*)
- 【時間】操作
- 時間函數例子
- Date/Time 函數(不包含別名函數)
- php網絡相關
- HTTP請求的返回值含義說明
- 使用php語言開發一個類似數據庫操作的文件表類
- pinyin
- 維吾爾語基本區轉換擴展區(2)
- php獲取當前環境的信息
- laravel
- laravel 隊列的使用
- laravel 自定義助手函數
- laravel seeder的使用
- laravel項目從git下載命令
- laravel 多個數據庫配置
- laravel 填充假數據
- laravel 動態路由
- laravel 自定義 validate 響應
- laravel 創建追加字段的模擬訪問器
- laravel 線上環境的數據庫更改或添加字段
- laravel 模型查詢按照whereIn排序
- laravel 使用 workerman 通過TCP 文件傳輸功能
- laravel api Header添加Accept頭
- Laraval IDE 自動補全插件 laravel-ide-helper
- laravel 網站后臺
- laravel 設置路由
- laravel-第三方composer包
- laravel 開發技巧
- laravel 昨天,今天時間
- 使用寶塔計劃任務啟動laravel調度器
- laravel結合workerman第二節
- Laravel - 上傳多個文件
- 查詢聊天好友列表
- 事件系統 event, listener
- laravel 安裝 laravel-modules
- 自定義求看守器-toekn
- laravel限流
- 使用 Laravel api Resource 類時自定義分頁信息
- Laravel php artisan命令大全
- 驗證器
- workerman 創建wss服務
- 架構師必須知道的26項PHP安全實踐
- python
- Python讀取文件代碼塊已經備好,用的時候光拿(建議收藏)
- Python常用庫大全
- api 簽名驗證
- git
- git命令
- 十分鐘學會git基礎
- Git代碼同時上傳到GitHub和Gitee(碼云)
- Git - 多人協同開發利器,團隊協作流程規范與注意事項
- 刪除遠程倉庫的文件
- github查詢方法
- 錯誤
- 解除項目git版本控制
- linux
- sentos安裝supervisor
- PHP怎么守護進程運行php腳本
- 600條最強Linux命令總結
- centos開啟防火墻、開放指定端口
- 前端
- vue
- vue2發布之前的config簡單配置
- vue2安裝scss命令
- vue2父子組件之間雙向數據綁定
- 國際化雙語--安裝VueI18n
- vue3-setup 組件傳參(defineProps、defineEmits、defineExpose
- Vue3 新寫法速覽:十分鐘內輕松get
- 關于vue的外連接
- watch講解
- computed
- webpack 打包后生成很多小文件怎么優化?
- vue2 vue.config.js常見配置和打包部署測試
- 小程序
- 小程序長期訂閱消息
- 小程序自定義TabBar后如何實現keep-alive
- 收藏的html和css和js
- CSS 省略號(單行省略號、多行省略號)
- UyghurInput_a.js
- font.css
- 漂亮按鈕樣式
- clock.html
- css
- scroll css樣式
- CSS流動布局-頁面自適應
- css grid布局
- 禁止wap頁面調整字體大小
- CSS @media 和 min-width/max-width
- 網站變灰是怎么實現的
- 瀑布流實現方式
- javascript
- SortableJS拖動排序
- wondow scroll滾動到上邊
- 原生js插入HTML元素
- Konva.js —— 像操作DOM一樣操作canvas
- 通過canvas合并倆個圖片
- js scroll更多加載
- js 實現復制功能
- js判斷安卓和蘋果或者微信
- 瀏覽器打開控制臺禁止
- 原生js一些dom操作
- js http客戶端集合
- fetch
- axios
- canvas 點鐘
- layer dialog
- jquery 和 laravel ajax全局配置
- layui 獲取select的自定義參數
- konva.js中文開發文檔
- js 大文件分片上傳
- js監聽網絡狀態實現斷網重連后自動刷新頁面
- js生成video縮略圖
- JS獲取當前系統電量情況
- uniapp
- uni-app swiper數量過多時卡頓優化方案
- uniapp 帖子集合
- 微信wap
- wap分享朋友和朋友圈
- wap 手機頁面微信支付
- JsSdk微信公眾號支付
- 通用各種小知識
- 正則表達式
- JS正則匹配過濾字符串中的html標簽及html標簽內的內容
- 判斷維吾爾文輸入
- 正則表達式符號
- 正則表達式練習
- 百度網盤不限速下載助手
- 解決VSCode下載慢或下載失敗的問題
- 性能測試 使用Apache的ab測試工具
- nginx從入門到精通
- nginx
- Nginx 是怎么禁止訪問php的 ?
- 寶塔面板
- supervisor
- 卸載寶塔
- redis
- redis實用筆記
- redis入門到精通
- phpredis
- redis數據庫基礎
- PHP對Redis的基本操作
- ffmpeg
- 合并多個音視
- 獲取音視時長
- FFmpeg視頻處理入門教程(新手必看)
- 外連接
- 安裝
- PHP基于ffmpeg實現轉換視頻,截圖及生成縮略圖的方法
- Linux安裝ffmpeg
- docker
- 服務實現
- docker基本命令
- rewrite筆記
- 別人筆記鏈接
- 計算機常用知識
- 二進制1-10
- 斐波那契數列
- mysql
- 高性能高可用的MySQL,得從各種規范開始
- 讀寫分離配置
- 重要外連接,前端/ 后端/數據庫等等
- 關于程序必須收藏的文章鏈接集合
- markdown
- 一篇文章講清楚markdown