摘要:語法如下是簡寫屬性,也可以分別定義行間隔和列間隔。語法如下屬性值得含義同這里不再過多說明,讀者可以自行驗證。
前言
在上篇——JavaScript五十問——對比來說CSS的Grid與FlexBox(上篇),我介紹了Flex的屬性與使用,今天我們來總結一下Grid的具體使用方法,最后會結合Flex與Grid布局講一講二者的聯系與不同。
需要注意得是,Grid布局與我們之前所熟悉的css布局思路有很大的不同,閱讀這篇文章之前,需要把我們平時對css的刻板印象拋棄掉,準備接受知識的洗禮吧,少年!
Grid與 Flex 相同,Grid 也分為容器與元素兩個概念;在一個 html 標簽中添加樣式:display:grid或者display:inline-grid,即構建了一個 Grid 的容器,里面的 dom 元素即為 Grid 元素。同樣,Grid 也分為兩類屬性,分別裝載在容器與元素上,下面一一說明。
HTML結構說明以下所有例子均基于或擴展于下面的HTML結構:
Grid 基本概念介紹 網格12345
Grid容器里面有網格一系列的概念;聽著唬人,但是結合圖很容易理解。
網格線水平方向有垂直方向的線段即為網格線
兩個相鄰的平行網格線之間的區域就是網格軌道
四個相鄰邊組成的區域就是網格單元。
fr是Grid中特有表示尺寸的單位,是分數——fraction的縮寫,假設我們現在有四個grid元素,每個元素的寬度都是1fr,那么每個元素的實際寬度就是總寬度的1/4。
fr也可以跟%,px 共同使用,他的計算規則就是刨去px與%的剩余空間作為fr分配空間,所有fr相加之和作為分母,分子為每個元素對應的fr的值。(當然,在Grid語境下,我們是不需要設置width屬性的,這樣說是為了讓大家容易理解)。
這樣說來好像fr僅僅是%的另外一種寫法,隨著我的介紹,你就會發現fr優于%的地方。
接下來,我還是以腦圖為思路介紹Grid的各個屬性。
grid-tempalte是三個屬性的簡寫,這三個屬性都是描述整塊區域即多個網格單元的屬性。
grid-template-rowsgrid-template-rows是描述橫向的單元軌道屬性的。可以試想一下,我們在一個Grid容器中,關于這個屬性,我們關心的是什么呢?無非就是這個容器中有多少行,每行的高度;所以,這個屬性就是讓我們定義這些值得。先來看語法:
grid-template-rows:
這個屬性除了可以定義軌道尺寸和個數之外,還允許我們定義兩個軌道之間的網格線的名稱,至于他的作用,我們先按下不表,先來看這個屬性是怎樣定義每個軌道的尺寸和軌道個數的。
先來看一個例子:
.container{ grid-template-rows:200px auto 1fr 1fr 20%; grid-row-gap:10px;//定義軌道之間的間距 }
grid-template-rows定義了五個值,表示Grid容器里面有五行,可以使用任意的定義尺寸的方式,效果如下
其中auto值就表示元素的實際占用大小。
Grid分配空間首先計算除了fr對應軌道的尺寸,然后將剩余尺寸按照比例分配給fr加持的元素。
以上,我們在Grid容器里定義了五行容器軌道,當我們定義軌道過多時,可以使用repeat函數來減少我們的工作量,語法為:
grid-template-rows:repeat(n, size)
例子:
.container{ grid-template-rows:repeat(5,1fr); grid-row-gap:10px; }
上面就定義了五個網格軌道,每個軌道的高度是Grid容器高度的1/5。
grid-template-columns 與 grid-template-rows使用方法是一致的,這兩個屬性共同作用于Grid容器,相當于把Grid容器分割為m*n個子區域。
例子:
.container{ grid-template-rows:repeat(3,1fr); grid-template-columns: repeat(2, 1fr)
上面這個例子就會得到六個均等分的子區域。
通過上面兩個屬性,相信大家對Grid布局有一個基本的認識了,想必對Grid二維布局的模式也有一些概念了,接下來才是Grid精彩之處,震撼靈魂的地方!
grid-template-areas上面兩個屬性分別設置Grid行屬性和列屬性,grid-template-areas是設置Grid區域的。所謂區域是由一個或多個行、列、單元組成的一篇區域。首先看一下語法:
.container { grid-template-areas: "| . | none | ..." "..."; }
其中
grid-area-name表示網格區域的名稱
.表示空的網格區域
none 表示沒有定義網格區域
在我們平時開發時,經常會出現上頭下尾中間兩欄布局的情況,下面我們使用grid-template-areas完成這樣的布局。
.container{ display:grid; grid-template-rows:60px 1fr 60px; grid-template-columns:100px 1fr; grid-template-areas: "header header" "left right" "footer footer"; } .container .item:first-child{ grid-area: header; } .container .item:nth-child(2){ grid-area: left; } .container .item:nth-child(3){ grid-area: right; } .container .item:nth-child(4){ grid-area: footer; } .container{ display:grid; grid-template-rows:60px 1fr 60px; grid-template-columns:100px 1fr; grid-template-areas: "header header" "left right" "footer footer"; } .container .item:first-child{ grid-area: header; } .container .item:nth-child(2){ grid-area: left; } .container .item:nth-child(3){ grid-area: right; } .container .item:nth-child(4){ grid-area: footer; }1234
在Grid容器中,我們定義了6個網格單元,使用grid-tempalte-areas劃分了header footer left right 四片區域;而在grid元素中,每個元素使用grid-area來指定元素所對應的grid區域。因此,我們雖然劃分了6個單元,但可以使用四個元素來表示。
是不是很神奇呢,更神奇的是,grid-area-name是支持中文定義的。
以上grid-template的子屬性就說完了,grid-template是以上那三個屬性的簡寫方式,語法如下:
grid-tempalte:<"grid-template-rows"> / <"grid-template-columns">` `grid-tempalte:[? ? ? ]+ [ / ]?
例如上面的例子可以這樣簡寫
grid-template: "header header" 60px "left right" 1fr "footer footer" 60px / 50px 1fr;grid-gap
grid-gap用來描述Grid 區域之間間隙的尺寸大小。語法如下:
.container { grid-gap:; }
grid-gap是簡寫屬性,也可以分別定義grid行間隔和grid 列間隔。
.container{ grid-row-gap:10px; grid-column-gap:10px; }
grid-gap與margin與padding不同,它不占用當前元素的盒模型的位置。
上圖顯示的很清楚,3號元素的margin 與 padding 均為零。
place-items 是 justify-items和align-items的簡寫方式
這兩個屬性分別定義了Grid元素水平與垂直分布方式。
語法如下:
justify-items: stretch | start | end | center; align-items: stretch | start | end | center;
對于這四個屬性,默認stretch,相信讀者在熟悉了Flex布局后都不會陌生,這里不多做解釋,直接看例子,以align-items 為例:
.container{ display:grid; grid-template: "header header" 160px "footer footer" 160px / 160px 160px; height:500px; grid-row-gap:10px; grid-column-gap: 10px; }
首先定義四個grid單元,每個單元的長寬均為160px
接下來我們更改align-items的值
align-items:stretch
align-items:center
align-items:start
align-items: end
為了方便大家理解,我用紅框框出每個Grid單元所占用的空間。由此可以看出,place-items屬性是用來表明一個元素在當前grid單元中的分布方式,這個元素的拉伸,居中等都是以grid單元作為參考的。
place-content同樣是一個簡寫屬性,它包括:justify-content 和 align-content,它表示grid元素在grid容器中的分布方式,只有當grid容器中有剩余空間的時候才起作用。
語法如下:
justify-content: stretch | start | end | center | space-between | space-around | space-evenly; align-content: stretch | start | end | center | space-between | space-around | space-evenly;
屬性值得含義同Flex;這里不再過多說明,讀者可以自行驗證。
grid-auto-rows 與 grid-auto-columnsgrid-auto-rows 和 grid-auto-columns;用于當實際的Grid的元素多余劃分的Grid元素時,定義多余Grid元素的長寬;
例如我們在HTML里面一定了五個Grid元素,但是在css中只定義了2*2的Grid單元,可以使用grid-auto來定義多出來的軌道的尺寸。
grid-auto-flow的用法需要結合下面的元素屬性來說明。
元素屬性 grid-column-start grid-column-end兩個屬性是用來定義Grid元素列方向上的起始與終止位置。
語法格式為:
grid-column-start:| | span | span | auto
其中:
number為起止第幾條網格線
name 為網格線的名稱
span
span
注意 使用span 如果是start,表示這個從開始的位置跨過的grid單元,如果是end 表示這個元素覆蓋的grid單元。
grid-column是它們的簡寫方式,語法為:
grid-column:grid-column-start / grid-column-endgrid-row-start grid-row-end
grid-row屬性與grid-column用法一致,這里不過多贅言,直接看例子:
.container{ display:grid; grid-template-rows:[rone]1fr[rtwo]3fr[rthree]1fr[rfour]; grid-template-columns: [cone]1fr[ctwo]5fr[cthree]2fr[cfour]; height:500px; } .item:first-child{ grid-column-start:1; grid-column-end:cfour; grid-row-start:rone; grid-row-end: 2; } .item:nth-child(2){ grid-column-start:1; grid-column-end:span 1; grid-row-start:rtwo; grid-row-end: span cthree; } .item:nth-child(3){ grid-column-start: ctwo; grid-column-end:4; grid-row-start:rtwo; grid-row-end: span cthree; } .item:nth-child(4){ grid-column-start:1; grid-column-end:4; grid-row-start:3; grid-row-end: span 4; }
效果:
首先在Grid容器中劃分出9個grid單元,這九個單元被六個網格線所分割,并給這六個網格線命名。在四個Grid元素中定義橫行的起始位置。
grid-row 與 grid-column結合使用,可以起到與Grid-template-areas同樣的效果。
grid-area我們在前面已經接觸過一部分了,他與Grid容器中的grid-template-areas一起定義,也是grid-column與grid-row的簡寫屬性,語法為:
grid-area:| / / / ;
name為grid區域的名稱,與grid-tempalte-areas結合使用。
上面我們的例子就可以用grid-area表示:
.item:first-child{ grid-area:1/rone/2/cfour; }place-self justify-self
justify-self定義Grid元素的水平布局方式的,例如,我們在Grid容器中定義justify-items的屬性為默認屬性,而在某一個Grid元素中定義justify-self為center,那么其他元素表現為拉伸,這個元素則多帶帶表現為居中。也就是說,justify-self在Grid容器中對應的屬性是justify-items。
語法為:
.item { justify-self: stretch | start | end | center; }algin-self
align-self與justify-self一致,改變的是這個元素的垂直部署方式,與容器中align-items對應,
語法為:
.container { align-self: stretch | start | end | center; }
由于這四個屬性值已經在我們的系列文章中出現多次,這里不再多說。
plac-self是以上兩個屬性的簡寫方式,語法為:
.container { place-items:再論fr/ ; }
Grid的所有屬性已經介紹完畢了,在對Grid宇宙有了一個基本的認識后,我們再回頭看一下Grid宇宙中出現的新尺寸單位——fr。
可能大家在剛剛結仇到fr這個單位時,都會認為它是%的一個別名;但是,我們來看最下面的例子:
我們在Grid容器中劃分出四個Grid區域,并定義每個區域的寬度為25%,并定義每個Grid元素之間的gap寬70px;
.container{ display:grid; grid-template-columns: repeat(4, 25%); grid-column-gap: 70px; }
效果如下:
很明顯,這里元素溢出了。這種情況是我們不想看到的。
下面,我們將25%替換為1fr看一下效果:
效果對比很明顯。
而造成兩者顯著區別的原因是二者的計算空間方式的不同。使用百分比它的分母是父元素的width或者height,而fr的分母是父元素中剩余空間的尺寸;css會首先計算使用%和px定義的元素尺寸,剩下的空間再由fr元素進行比例分配。這就是使用fr不會出現元素溢出的情況。當然我們也可以使用calc避免溢出的尷尬,但是兩種解決方案孰優孰略已經一目了然了。
Flex布局與Grid布局有很多相似的地方,例如justify-content和justify-items的用法。但是更多的是不同,最重要的是Grid開拓了二維布局的方式,相比于傳統的css布局方式(Flex、bootstrp 12列),Grid開創了網格的概念,用戶可以從橫縱兩個方面部署元素。正是因為如此,在Grid宇宙中,傳統的css布局、尺寸屬性就顯得格格不入了。而Grid布局的二維特性所帶來的整體觀,使Grid在頁面級別樣式上更加游刃有余。而Flex相比于Grid 更加適合小組件上的樣式開發,二者并不沖突相信在Grid 與 Flex雙雙加持之下,一定會收獲更好的開發效果!
Grid布局還是一個較新潮的概念,我也是一般看資料學習,一邊分享,由于缺少實際的開發經驗,對于很多屬性的應用場景還沒有很深入的理解,故而有的屬性一筆帶過;如果我有理解不正確的地方,歡迎大家指正!
MDN:Grid Layout
張鑫旭:寫給自己看的display: grid布局教程
知乎:CSS 新的長度單位 fr 你知道么?
JavaScript五十問——對比來說CSS的Grid與FlexBox(上篇)
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/117410.html
摘要:前言春節假期有幸拜讀了張鑫旭大大的關于與的兩篇文章見參考文獻,很有收獲自己在開發的過程中,很多時候都會采用布局,而與這種方式已經很少使用了這次在春假期間學習了,深感的好用與便利。相對于,它多出來一個的屬性,代表拉伸默認屬性。 前言 春節假期有幸拜讀了張鑫旭大大的關于Flex與Grid的兩篇文章(見參考文獻),很有收獲;自己在開發的過程中,很多時候都會采用Flex布局,而Float與in...
摘要:前言無論是面試還是在討論瀏覽器優化過程中,都會涉及到去抖動和節流的問題。總的來說,這二者是一種限制事件觸發頻率的方式。不同的是,節流會指定事件觸發的時間間隔而去抖動會指定事件不觸發的時間間隔。 前言 無論是面試還是在討論瀏覽器優化過程中,都會涉及到去抖動和節流的問題。總的來說,這二者是一種限制事件觸發頻率的方式。不同的是,節流會指定事件觸發的時間間隔;而去抖動會指定事件不觸發的時間間隔...
摘要:前言無論是面試還是在討論瀏覽器優化過程中,都會涉及到去抖動和節流的問題。總的來說,這二者是一種限制事件觸發頻率的方式。不同的是,節流會指定事件觸發的時間間隔而去抖動會指定事件不觸發的時間間隔。 前言 無論是面試還是在討論瀏覽器優化過程中,都會涉及到去抖動和節流的問題。總的來說,這二者是一種限制事件觸發頻率的方式。不同的是,節流會指定事件觸發的時間間隔;而去抖動會指定事件不觸發的時間間隔...
摘要:前言與是目前圈子內比較活躍的前端構建工具。對于初學者來說,對這二者往往容易認識不清,今天,就從事件的源頭,說清楚與。它可以將許多松散的模塊按照依賴和規則打包成符合生產環境部署的前端資源。打包后形成的文件出口。 前言:Webpack 與 gulp是目前圈子內比較活躍的前端構建工具。網上有很多二者比較的文章,面試中也會經常遇到gulp,Webpack的區別這樣的問題。對于初學者來說,對這二...
摘要:組合繼承實現了屬性分離,方法共享下的完美繼承方案繼承我們的主角,,就是對組合繼承的改進。這也是為什么在子類構造函數中一定要顯示調用的原因。 談到繼承,或者更廣義上的:一個對象可以使用另外一個對象的屬性或方法。實現起來無外乎有兩種方式:apply or call 改變this的作用域原型繼承 改變__proto__指向,添加作用域鏈 而JavaScript所有的繼承實現,都是圍繞以上兩點...
閱讀 1857·2021-09-22 15:45
閱讀 1639·2019-08-30 15:55
閱讀 1828·2019-08-29 11:16
閱讀 3301·2019-08-26 11:44
閱讀 701·2019-08-23 17:58
閱讀 2697·2019-08-23 12:25
閱讀 1623·2019-08-22 17:15
閱讀 3596·2019-08-22 16:09