Css權(quán)威指南(4th,第四版中文翻譯)-13.Grid布局

其實在CSS早期,布局這塊一直是個空白,只能通過類似于Float,clear等hack技術(shù)來完成布局。到后面flexble box的出現(xiàn)極大擴展了布局的功能,但是flex更適合于細節(jié)的布局,例如導航欄,而全局的布局知道Grid出現(xiàn)才有了較大的進步。


創(chuàng)建一個Grid容器

創(chuàng)建grid的第一步就是定義一個grid的容器(container),類似于定位中的容器盒子。grid分為兩類:普通的regular grid和inline grid。跟flex一樣,都需要在容器元素的display屬性值進行申明:


image.png

雖然grid在很多時候和block很類似,不過他們也有以下的區(qū)別:

  1. 浮動元素在grid容器中無效:


    image.png
  2. grid容器的margin并不會與子代的margin合并


    image.png

同時也有一些CSS屬性是對grid元素無效的:

  • 所有的column屬性
  • ::first-line ::first-letter
  • float, clear
  • vertical-align

基本的Grid術(shù)語

基本的元素名稱匯總?cè)缦拢?/p>

image
  • grid track: 其實是橫向和縱向的長度;
  • grid cell:是由4條網(wǎng)格線(grid line)所包圍的最小區(qū)域;
  • grid area:網(wǎng)格區(qū)域就是有網(wǎng)格線包圍的區(qū)域,可能有一個或多個cell組成。

放置Grid Lines

放置grid line還是比較復雜的,來看下下面這兩個屬性:


image.png

首先我們來試試創(chuàng)建固定寬度的格點:

#grid {display: grid; grid-template-columns: 200px 50% 100px;}
image.png

而且有意思的是,你開可以為你的grid line設(shè)置名稱,放到[]里面就可以:

#grid {display: grid; grid-template-columns:
            [start col-a] 200px [col-b] 50% [col-c] 100px [stop end last];
        }
image.png

row方向的配置和column是一致的:

#grid {display: grid; grid-template-columns:
[start col-a] 200px [col-b] 50% [col-c] 100px [stop end last]; grid-template-rows:
            [start masthead] 3em [content] 80% [footer] 2em [stop end];
        }
image.png

有時候我們想要區(qū)間的范圍設(shè)定一個范圍而不是個具體的值,那么就可以借助minmax來實現(xiàn):

#grid {display: grid; grid-template-columns:
[start col-a] 200px [col-b] 50% [col-c] 100px [stop end last]; grid-template-rows:
            [start masthead] 3em [content] minmax(3em,100%) [footer] 2em [stop end];
        }

image.png

另外還可以借助calc來做計算,如果要計算剩余范圍的話:

grid-template-rows:
[start masthead] 3em [content] calc(100%-5em) [footer] 2em [stop end];

flexible grid 軌跡

之前我們看到的都是定死的grid配置,那么現(xiàn)在來看看grid的彈性配置。我們用的單位比較特別,稱為分數(shù)單位(Fractional units),簡稱為fr。

grid-template-columns: 1fr 1fr 1fr 1fr;
grid-template-columns: 25% 25% 25% 25%;

上面兩個操作其實效果是一樣的:


image.png

grid 適配內(nèi)容大小

除了上面的彈性布局,其實CSS還提供了針對內(nèi)容的適配,有min-conten, max-content還有fit-content。

#g1 {display: grid;
grid-template-columns: max-content max-content max-content max-content; }
#g2 {display: grid;
grid-template-columns: minmax(0,max-content) minmax(0,max-content)
              minmax(0,max-content) minmax(0,max-content);
        }

image.png
#grid {display: grid; grid-template-columns: 1fr fit-content(150px) 2fr;}
#grid2 {display: grid; grid-template-columns: 2fr fit-content(50%) 1fr;}

fit-content(argument) => min(max-content, max(min-content, argument))

#thefollowing { display: grid;
grid-template-columns:
fit-content(50ch) fit-content(50ch) fit-content(50ch);
font-family: monospace;}

image.png

重復格線

想要實現(xiàn)重復的格線,利用repeat函數(shù)會更加方便,比如要產(chǎn)生10個5em寬度的區(qū)域就可以寫成:

#grid {display: grid; grid-template-columns: repeat(10, 5em);}

而且repeat的后面參數(shù)是可以持續(xù)添加的,比如:

#grid {display: grid;
grid-template-columns: repeat(3, 2em 1fr 1fr);}
image.png

Grid 區(qū)域

image.png

網(wǎng)格區(qū)域是用來標志區(qū)域的,來看下:

#grid {display: grid; grid-template-areas:
            "h h h h"
            "l c c r"
            "l f f f";}
image.png

可以是更形象的:

#grid {display: grid; grid-template-areas:
            "header     header    header    header"
            "leftside   content   content   rightside"
            "leftside   footer    footer    footer";}

將元素添加到Grid

之前我們都是在講怎么定義grid,現(xiàn)在講講怎么把元素放到grid里面。

使用column和row線

image.png
.grid {display: grid; width: 50em; grid-template-rows: repeat(5, 5em); grid-template-columns: repeat(10, 5em);}
.one {
grid-row-start: 2; grid-row-end: 4; grid-column-start: 2; grid-column-end: 4;}
.two {
grid-row-start: 1; grid-row-end: 3; grid-column-start: 5; grid-column-end: 10;}
.three {
grid-row-start: 4; grid-column-start: 6;}

這個通過設(shè)置row和column兩個方向的起點和終點來規(guī)定元素在grid所占用的位置。


也可以用span來標識要跨幾個格點:

#grid {display: grid;
grid-template-rows: repeat(5, 5em); grid-template-columns: repeat(10, 5em);}
.one {
grid-row-start: 2; grid-row-end: span 2; grid-column-start: 2; grid-column-end: span 2;}
.two {
grid-row-start: 1; grid-row-end: span 2; grid-column-start: 5; grid-column-end: span 5;}
.three {
grid-row-start: 4; grid-row-end: span 1; grid-column-start: 6; grid-column-end: span;}

row和column的簡寫

image.png

這兩個屬性極大簡化了選擇的操作,來看例子:

#grid {display: grid;
grid-template-rows: repeat(10, [R] 1.5em);
grid-template-columns: 2em repeat(5, [col-A] 5em [col-B] 5em) 2em;}
.one {
grid-row: R 3 / 7; grid-column: col-B / span 2;}
.two {
grid-row: R / span R 2;
grid-column: col-A 3 / span 2 col-A;}
.three { grid-row: 9;
grid-column: col-A -2;}
#grid {display: grid; grid-template-areas:
            "header header"
            "sidebar content"
            "footer footer";
grid-template-rows: auto 1fr auto;
grid-template-columns: 25% 75%;}
#header {grid-row: header / header; grid-column: header;}
#footer {grid-row: footer; grid-column: footer-start / footer-end;}
image.png

同時也可以通過area的名稱來做范圍的選擇:


#grid {display: grid; grid-template-areas:
            "header header"
            "sidebar content"
            "footer footer";
grid-template-rows: auto 1fr auto;
grid-template-columns: 25% 75%;}
#header {grid-row: header / header; grid-column: header;}
#footer {grid-row: footer; grid-column: footer-start / footer-end;}
image.png

使用區(qū)域

image.png

借助grid-area可以直接讓元素綁定之前定義好的區(qū)域:


#grid {display: grid; grid-template-areas:
            "header     header    header    header"
            "leftside   content   content   rightside"
            "leftside   footer    footer    footer";}
#masthead {grid-area: header;} #sidebar {grid-area: leftside;} #main {grid-area: content;} #navbar {grid-area: rightside;} #footer {grid-area: footer;}
<div id="grid">
<div id="masthead">...</div> <div id="main">...</div> <div id="navbar">...</div> <div id="sidebar">...</div> <div id="footer">...</div>
</div>
image.png

Grid Flow

之前我們講到的是用戶自己定義grid元素位置的情況,那么如果不指定的話有沒有自動填充的方式么?答案是有的,就是使用grid-auto-flow


image.png
<ol id="grid"> <li>1</li> <li>2</li> <li>3</li> <li>4</li> <li>5</li> </ol>
#grid {display: grid; width: 45em; height: 8em; grid-auto-flow: row;}
#grid li {grid-row: auto; grid-column: auto;}
image.png

grid 簡寫

image.png
grid:
"header header header header" 3em ". content sidebar ." 1fr
"footer footer footer footer" 5em / 2em 3fr minmax(10em,1fr) 2em;
grid-template-areas:
"header header header header" ". content sidebar ."
"footer footer footer footer";
grid-template-rows: 3em 1fr 5em; grid-template-columns: 2em 3fr minmax(10em,1fr) 2em;

打開Grid間的空隙

之前我們所有的grid都是緊挨著的,接下來我們來看下如何在其中添加空白。


image.png
#grid {display: grid; 
grid-template-rows: 5em 5em;
grid-template-columns: 15% 1fr 1fr; 
grid-column-gap: 1em;}
image.png

另外一個添加gap的屬性是:


image.png
#grid {display: grid; grid-template-rows: 5em 5em; grid-template-columns: 15% 1fr 1fr; grid-gap: 12px 2em;}

image.png

Grid對齊

grid 元素的對齊和flexbox其實是很像的,來看下對照表:


image.png
#grid {display: grid;
align-items: center; justify-items: center;}
image.png

圖層及其排序

grid元素支持重疊,例如:

#grid {display: grid; width: 80%; height: 20em;
grid-rows: repeat(10, 1fr); grid-columns: repeat(10, 1fr);}
.box01 {grid-row: 1 / span 4; grid-column: 1 / span 4;} .box02 {grid-row: 4 / span 4; grid-column: 4 / span 4;} .box03 {grid-row: 7 / span 4; grid-column: 7 / span 4;} .box04 {grid-row: 4 / span 7; grid-column: 3 / span 2;} .box05 {grid-row: 2 / span 3; grid-column: 4 / span 5;}
image.png

所以可以通過設(shè)置z-index來調(diào)整圖層的前后順序:


image.png

另一種方式的排序就是使用order屬性:

.box02 {order: 10;}
image.png

小結(jié)

grid布局還是比較復雜的,不過功能也非常強大。作者自己有時候也被搞暈了,但還是希望能夠克服這些,因為你付出的耐心和堅持的回報會是巨大的。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 簡介CSS網(wǎng)格布局(又稱“網(wǎng)格”),是一種二維網(wǎng)格布局系統(tǒng)。CSS在處理網(wǎng)頁布局方面一直做的不是很好。一開始我們用...
    _leonlee閱讀 65,766評論 25 173
  • 上一篇,介紹了grid的瀏覽器兼容和重要的幾個概念,接下來繼續(xù)介紹grid的容器屬性。 Grid(網(wǎng)格) 屬性目錄...
    codeTao閱讀 2,199評論 0 1
  • 簡介 CSS Grid布局 (又名"網(wǎng)格"),是一個基于二維網(wǎng)格布局的系統(tǒng),旨在改變我們基于網(wǎng)格設(shè)計的用戶界面方式...
    咕咚咚bells閱讀 2,700評論 0 4
  • 前言 之前寫過一篇關(guān)于flex的布局,但是發(fā)現(xiàn)很多的問題,flex布局雖然可以解決,但是解決起來比較復雜,究其本質(zhì)...
    kim_jin閱讀 965評論 2 3
  • 為什么不結(jié)婚,因為沒有遇到感覺對的人;為什么離婚,因為沒有感覺了;為什么出軌,因為我想要那樣的感覺。 感覺是什么...
    一個人飄零閱讀 225評論 0 1

友情鏈接更多精彩內(nèi)容