網格佈局(Grid)是最強大的 CSS 佈局方案,比flex還要強大。瀏覽器
它將網頁劃分紅一個個網格,能夠任意組合不一樣大小的網格,作出各類各樣的佈局。
如上面的圖,正是Grid佈局的應用,還有好比 管理系統的主頁 dashboard,正是應用了grid佈局實現的。ide
Flex 佈局是軸線佈局,只能指定"項目"針對軸線的位置,能夠看做是一維佈局。Grid 佈局則是將容器劃分紅"行"和"列",產生單元格,而後指定"項目所在"的單元格,能夠看做是二維佈局。函數
容器:採用網格佈局的元素佈局
項目:容器的直接子元素(和孫子元素無關)flex
行: 容器裏面的水平區域spa
列: 容器裏面的垂直區域3d
單元格:行和列的交叉區域code
網格線:水平網格線劃分出行,垂直網格線劃分出列。
正常狀況下,n行有n + 1根水平網格線,m列有m + 1根垂直網格線,好比三行就有四根水平網格線。blog
Grid屬性: 在grid佈局中,有兩類屬性,一類是定義在容器上的,一類是定義在項目中的。it
給對應元素設置 display:grid或者 inline-grid
<div class="container"> <span class="item item-1">1</span> <span class="item item-2">2</span> <span class="item item-3">3</span> <span class="item item-4">4</span> <span class="item item-5">5</span> <span class="item item-6">6</span> </div>
.container { display: grid; }
默認狀況下,子元素都是塊級元素,而且默認只有一列(即grid-template-columns: 只有一個值;)
若是將其設置爲display: inline-grid;則能夠看到照樣是一列,只是寬度沒有100%平鋪,而是實際寬度。
注意: 設爲網格佈局之後,容器項目的float、display:inline-block、display:table-cell、vertical-align和column-*等設置都將失效。
定義每一列的列寬。
.container { display: grid; grid-template-columns: 100px 100px 100px; }
有幾個值,代表指定了幾列,沒定義列寬的列會自動跑到下一行,而多餘的列會佔用空間。
以下圖:
表示採用父元素寬度的百分比定義當前列的寬度。
.container { display: grid; grid-template-columns: 33% 33%; }
表示重複,第一個參數爲幾回,後面參數表示每次的值是多少
.container { display: grid; grid-template-columns: repeat(3, 33.33%); }
repeat(3, 33.33%);等於 33.33% 33.33% 33.33%
好比,每列是固定的寬度,但是一行究竟放幾列呢?不知道,只知道隨着屏幕寬度大小,自動補充剩餘空間。
fr表示比例關係
.container { display: grid; grid-template-columns: 1fr 2fr; //表示定義兩列,這兩列爲1比2 }
上面grid-template-columns: 1fr 2fr;等同於 grid-template-columns: 33.33% 66.66%;
甚至能夠這麼寫
grid-template-columns: 150px 1fr 2fr;
minmax()函數產生一個長度範圍,表示長度就在這個範圍之中。它接受兩個參數,分別爲最小值和最大值。
.container { display: grid; grid-template-columns: 1fr 1fr minmax(200px, 1fr); }
表示由瀏覽器本身決定長度。
.container { display: grid; grid-template-columns: 50px auto auto auto; }
上面grid-template-columns: 50px auto auto auto;等同於
grid-template-columns: 50px 1fr 1fr 1fr;
定義每一行的行高,默認爲子元素的行高
.container { display: grid; grid-template-rows: 100px 100px 100px; }
有幾個值,代表指定了幾行,沒定義的行會採用默認的行高(不會自動跑到下一列),而多餘的行,會佔用空間
如圖,只定義了前三行,後面三行均採用默認值。
默認先按grid-template-columns計算列數,而後自動計算行數。
當grid-template-columns和grid-template-rows組合是會出現,不匹配的狀況。
好比一共6個項目,我定義了3列(
grid-template-columns),那麼也就是自動2行,可是此時又指定了3行(grid-template-rows),那麼此時就是3*3的網格。
而又有 一共6個項目,我定義了3列,那麼自動就是2行,此時又指定1行,那麼此時不會是31,仍是32.
其中grid-template-columns和grid-template-rows指定的網格,咱們能夠稱爲標準網格,
而當實際的項目比定義的標準網格要多時。咱們稱超出的部分,爲擴展網格。
標準網格和擴展網格共同組成了Grid佈局的網格。
後面咱們會經過另外的屬性對於擴展網格定義寬高。
劃分網格之後,容器的子元素會按照順序,自動放置在每個網格。默認的放置順序是"先行後列",即先填滿第一行,再開始放入第二行,即下圖數字的順序。
grid-auto-flow默認值爲row,即"先行後列"。若是爲column,則先列後行。
.container { display: grid; grid-template-columns: 100px 168px 100px; grid-template-rows: 137px 100px 100px; grid-auto-flow: row; }
.container { display: grid; grid-template-columns: 100px 168px 100px; grid-template-rows: 137px 100px 100px; grid-auto-flow: column; }
grid-auto-flow不論是row仍是column,都是後面的列排不下了,那麼會換行,此時,前一行後面就會有空白。
而若是設置成row dense和column dense,則前一行的空白會按順序找出第一個能恰好放下的元素補齊。
.container { display: grid; grid-template-columns: 100px 168px 100px; grid-template-rows: 137px 100px 100px; grid-auto-flow: row; } .item-1{ grid-column-start: 1; grid-column-end: 3; } .item-2{ grid-column-start: 1; grid-column-end: 3; }
此時會看到右上方有個空白,由於item-3是緊跟在item-2後面的。
.container { display: grid; grid-template-columns: 100px 168px 100px; grid-template-rows: 137px 100px 100px; grid-auto-flow: row dense; } .item-1{ grid-column-start: 1; grid-column-end: 3; } .item-2{ grid-column-start: 1; grid-column-end: 3; }
而若是改爲row dense,則會發現item-1和item-2沒法拍到item-1後,換行了,接着按順序找到了item-3補齊在item-1後面。
因此添加dense後,會「儘可能填滿空格」
設置行與行的間隔(行間距)
.container { display: grid; grid-template-columns: 100px 100px 100px; grid-template-rows: 100px 100px 100px; row-gap: 20px; }
設置列與列的間隔(列間距)
.container { display: grid; grid-template-columns: 100px 100px 100px; grid-template-rows: 100px 100px 100px; row-gap: 20px; column-gap: 20px; }
row-gap和column-gap能夠簡寫爲
gap:<row-gap> <column-gap>
若是gap省略了第二個值,瀏覽器認爲第二個值等於第一個值。
.container { display: grid; grid-template-columns: 100px 100px 100px; grid-template-rows: 100px 100px 100px; gap: 20px 20px; }
網格佈局容許指定"區域"(area)編號,以便在項目中使用。
(對現有佈局不會產生影響)
也能夠進行合併,即起一樣的名字
.container { display: grid; grid-template-columns: 100px 168px 100px; grid-template-rows: 137px 100px 100px; grid-template-areas: "header header header" "main main sidebar" "footer footer footer"; }
設置容器下全部單元格內容的水平位置(左中右),網格線不動,基於網格線的位置。它針對的是全部的單元格。
justify-items: start | end | center | stretch(默認);
.container { display: grid; grid-template-columns: 100px 168px 100px; grid-template-rows: 137px 100px 100px; justify-items: start; }
因爲不是stretch後,項目的寬度都是自身的寬
設置容器下全部單元格內容的垂直位置(上中下),網格線不動,基於網格線的位置。它針對的是全部的單元格。
align-items: start | end | center | stretch(默認);
.container { display: grid; grid-template-columns: 100px 168px 100px; grid-template-rows: 137px 100px 100px; align-items: start; }
上面的justify-items和align-items能夠合併成一個屬性:place-items
place-items: <align-items> <justify-items>;
.container { display: grid; grid-template-columns: 100px 168px 100px; grid-template-rows: 137px 100px 100px; place-items: start start; }
整個內容區域在容器裏面的水平位置(左中右),網格線會動,基於的是grid的邊緣。
justify-content: start | end | center | stretch | space-around | space-between | space-evenly;
space-around和space-evenly區別在與,space-around指項目和項目之間的距離相等,可是離邊緣是項目之間的一半,而space-evenly即便再邊緣也等於項目之間的距離。
.container { display: grid; width: 600px; height: 400px; background-color: antiquewhite; grid-template-columns: 100px 168px 100px; grid-template-rows: 137px 100px 100px; justify-content: space-around; }
.container { display: grid; width: 600px; height: 400px; background-color: antiquewhite; grid-template-columns: 100px 168px 100px; grid-template-rows: 137px 100px 100px; justify-content: space-evenly; }
整個內容區域在容器裏面的垂直位置(上中下),網格線會動,基於的是grid的邊緣。
align-content: start | end | center | stretch | space-around | space-between | space-evenly;
.container { display: grid; width: 600px; height: 400px; background-color: antiquewhite; grid-template-columns: 100px 168px 100px; grid-template-rows: 137px 100px 100px; align-content: space-around; }
.container { display: grid; width: 600px; height: 400px; background-color: antiquewhite; grid-template-columns: 100px 168px 100px; grid-template-rows: 137px 100px 100px; align-content: space-evenly; }
上面align-content和justify-content能夠合併爲 place-content。
place-content: <align-content> <justify-content>
.container { display: grid; width: 600px; height: 400px; background-color: antiquewhite; grid-template-columns: 100px 168px 100px; grid-template-rows: 137px 100px 100px; place-content: space-evenly space-around; }
用來設置,經過 grid-template-columns 和 grid-template-rows定義的標準網格大小,比實際的 項目數小時,多餘的項目,即擴展網格的列和行的大小。
默認狀況下多餘的列和行,會使用項目中元素的實際內容的大小。
.container { display: grid; grid-template-columns: 100px 168px 100px; grid-template-rows: 137px; }
定義了一個3列,1行的網格,一共能夠放置3個項目,而下面是6個項目,也就意味後,item-4到item-6是在網格以外的。那麼就使用自身元素的實際內容大小
<div class="container"> <span class="item item-1">1</span> <span class="item item-2">2</span> <span class="item item-3">3</span> <span class="item item-4">4</span> <span class="item item-5">5</span> <span class="item item-6">6</span> </div>
可是咱們能夠經過grid-auto-rows來顯示的指定,多餘的部分的行高。它隻影響多餘的項目,對原本的網格項目不會形成影響。
.container { display: grid; grid-template-columns: 100px 168px 100px; grid-template-rows: 137px; grid-auto-rows: 50px; }
用來設置,經過 grid-template-columns 和 grid-template-rows定義的網格大小,比實際的 項目數小時,多餘的項目的列和行的大小。
默認狀況下多餘的列和行,會使用項目中元素的實際內容的大小。
可是和grid-auto-rows不一樣的是,grid-auto-rows的多餘行,會採用自身元素實際的行高,而grid-auto-columns的多餘列,會填滿剩餘的空間(即便是span也是,奇怪)
.container { display: grid; grid-auto-flow: column; grid-template-columns: 100px; grid-template-rows: 100px 100px 100px; }
定義了一個1列,3行的,一供能夠放置3個項目。那麼第二列就是多餘的列。
使用grid-auto-columns後。
.container { display: grid; grid-auto-flow: column; grid-template-columns: 100px; grid-template-rows: 100px 100px 100px; grid-auto-columns: 20px; }
前面的12個屬性都是定義在容器上的,而下面的這些屬性則是定義在容器裏面的項目上的。
grid-column-start 定義項目垂直方向的 的起始網格(整數。好比grid-template-columns定義了3個值,那麼grid-column-start能夠取1到4)
grid-column-end 定義項目垂直方向的 的終止網格(整數。好比grid-template-columns定義了3個值,那麼grid-column-start能夠取1到4)
.container { display: grid; grid-template-columns: 100px 168px 100px; grid-template-rows: 137px 100px 100px; } .item-1{ grid-column-start: 1; grid-column-end: 3; }
item-1垂直方向從1開始,到3結束
grid-row-start 定義項目水平方向的 的起始網格(整數。好比grid-template-rows定義了3個值,那麼grid-column-start能夠取1到4)
grid-row-end 定義項目水平方向的 的終止網格(整數。好比grid-template-rows定義了3個值,那麼grid-column-start能夠取1到4)
.container { display: grid; grid-template-columns: 100px 168px 100px; grid-template-rows: 137px 100px 100px; } .item-1{ grid-column-start: 1; grid-column-end: 3; grid-row-start: 2; grid-row-end: 4; }
item-1垂直方向從1開始,到3結束, 水平方向從2開始,到4結束
上面的-start和-end能夠改爲網格線的名稱。
.container { display: grid; grid-template-columns: 100px 168px 100px; grid-template-rows: 137px 100px; grid-template-areas: "header header setting" "main main sidebar" }
上面第一行定義了兩列 header setting,因此他們的網格線分別爲 header-start,header-end和setting-start,setting-end。其餘也同樣。
.item-1{ grid-column-start: header-start; grid-column-end: header-end; grid-row-start: main-start; grid-row-end: footer-end; }
指定項目放在哪個區域
.container { display: grid; grid-template-columns: 100px 168px 100px; grid-template-rows: 137px 100px; grid-template-areas: "header header setting" "main main sidebar" }
.item-1{ grid-area: header; }
其實咱們發現
grid-area: header;
和下面的效果如出一轍
grid-row-start: header; grid-column-start: header; grid-row-end: header; grid-column-end: header;
設置單元格內容的水平位置(左中右),跟justify-items屬性的用法徹底一致,但只做用於單個項目。
justify-self: start | end | center | stretch;
.container { display: grid; grid-template-columns: 100px 168px 100px; grid-template-rows: 137px 100px; }
.item-1{ justify-self: center; }
設置單元格內容的垂直位置(上中下),跟align-items屬性的用法徹底一致,但只做用於單個項目。
align-self: start | end | center | stretch;
.container { display: grid; grid-template-columns: 100px 168px 100px; grid-template-rows: 137px 100px; }
.item-1{ align-self: center; }
還可用 place-self屬性place-self: <align-self> <justify-self>;