Grid-layout不是爲了取代flex-layout,它是flex的補充。grid擅長二維佈局,flex擅長一維佈局。他們須要各司其職。css
千呼萬喚始出來的grid-layout終於在2017年3月開始支持獲得了部分瀏覽器的支持。
css3
二維佈局方式,能夠按照行列方式排列內容。把頁面劃分爲幾塊,指定不一樣內容區塊的大小、位置和層級。算法
有觀點說grid很像table2.0,他們是有相同之處的。好比都是把元素排列成行和列。可是表格和grid的區別在於,表格是有內容結構的,不能很自由地在裏面作佈局。而grid內部元素能夠自由設定位置,容許重疊和設定層級的樣。segmentfault
網格容器爲其內容創建新的網格格式化上下文,是內部網格項的邊界。數組
水平垂直分割線,構建出網格軌道、網格單元格和網格區域。就像經緯,分割出南北半球、東西半球,熱帶、南北溫帶、南北寒帶。網格線是有數字索引的,也能夠本身取名字。經緯線都是有數字的,也能夠命名,好比本初子午線、赤道。瀏覽器
網格內容塊之間的水平或垂直的空間。濱盛、濱和、濱興、濱安、濱康,江陵、江暉、江漢、江虹。(郊區的經典命名,攤手)bash
網格內容的單位區塊,是能夠放置內容的最小區塊。好比用橫縱三條網格線劃分了頁面,那麼單元格就是九宮格中的一塊網絡
以網格線爲界劃定一塊區域。本來網易和阿里巴巴都是佔用一個單元格,如今都要擴建了,佔用兩個,兩個加起來就是它們各自的網格區域。框架
在瞭解具體的屬性以前,來一個最簡單的例子ide
這樣看會以爲grid仍是頗有趣的,先分塊,而後指定每一塊的區域範圍。塊是能夠重疊的。可是這只是開始,grid爲咱們帶來了17個新特性,在瞭解屬性以前再來看一個例子,經典佈局方案 —— 聖盃佈局 holy grail layout。
你們能夠迅速在腦子裏碼一下這個界面寫個樣式,不至於說複雜 但總之不簡單吧。咱們看看grid是怎麼作的
// key code
.hg__header { grid-area: header;}
.hg__footer { grid-area: footer;}
.hg__main { grid-area: main;}
.hg__left { grid-area: navigation;}
.hg__right { grid-area: ads;}
.hg {
display: grid;
grid-template-areas: "header header header"
"navigation main ads"
"footer footer footer";
grid-template-columns: 250px 1fr 300px;
grid-template-rows: 100px
1fr
80px;
min-height: 100vh;
}複製代碼
步驟:
定義網格
grid-area: main;
grid-row-start: main;
grid-column-start: main;
grid-row-end: main;
grid-column-end: main;複製代碼
設定單元格的高度和寬度
有一個css3的新單位,fr,在一串數值中出現的話表示根據比例分配某個方向上的剩餘空間。設定行高的時候分行寫是爲了清晰一點。
設定固定位置的頁腳
grid-template-columns: <track list>
,定義網格的行數、列數、網格大小。
有不少中形式,常見的是這麼幾種:
grid-template-columns: 100px 1fr;
grid-template-columns: [linename] 100px; // 定義網格線名字
grid-template-columns: [linename1] 100px [linename2 linename3]; // 一條網格線多個名字
grid-template-columns: minmax(100px, 1fr); // 最小100px, 最大滿屏
grid-template-columns: fit-content(40%); // 指定最大值不超過屏寬40%
grid-template-columns: repeat(3, 200px); // 三列200px複製代碼
// 給網格線指定名字
.box {
grid-template-columns: [first] 40px [line2] 50px [line3] auto [col4-start] 50px [five] 40px [end];
grid-template-rows: [row1-start] 25% [row1-end] 100px [third-line] auto [last-line];
}複製代碼
定義網格區域,使用grid-area調用聲明好的網格區域名稱放置對應的網格項目。定義一個顯式的網格區域。
定義網格之間的間距(不包括grid-item到容器邊緣的間距)
定義網格子項的內容水平方向上的對齊方式,相似於flex-container的justify-content,只不過沒有space-around和space-between
定義網格子項的內容垂直方向上的對齊方式,相似於flex-container的align-items
當出現網格容器容量大於網格總大小,好比每個網格子項都用了固定值的時候,指定網格在網格容器中和縱軸的對齊方式。後面三個屬性值的區別在:
space-evenly: 始末兩端的間距與網格間距相等
和justify-content對齊方向垂直,指定網格和橫軸的對齊方式。
grid-auto-columns | grid-auto-rows做用是網格單元格不夠的時候建立隱式的網格放置grid-item。看一個例子
咱們只定義了一個1×1的網格容器,box1放了進來,而後其餘的三個怎麼辦呢?漏出來。box2接在box1後面渲染至屏幕右側,box3和box4在底下渲染,高度僅僅爲內容高度。
指定了grid-auto-columns: 200px; grid-auto-rows: 200px;
,至關於在容器中橫縱都建立了更多的隱式的200*200的網格單元來盛放可能多出來的元素。
與之相關的還有另外一個屬性:grid-auto-flow,在咱們沒有設定這個屬性的時候,多餘的元素也按照從左到右從上到下的順序排列,這個屬性是控制自動佈局算法的。
grid-auto-flow: row | column | row dense | column dense;
grid-row: grid-row-start / grid-row-end
grid-column: grid-column-start / grid-column-end | grid-column-start | span <value>複製代碼
若是沒有顯式設置grid-column-end/grid-row-end,網格子項將默認跨越一個網格單元。此外,網格子項能夠互相重疊,可使用z-index來控制他們的層疊順序。
有一些元素,咱們想讓它貫穿整個視口,好比像 header、footer,對於小屏幕,兩列布局:
.header, .footer {
grid-column: 1 / 3;
}複製代碼
不幸的是,當咱們換到大屏的時候,一行12列,這些元素將僅僅佔滿前兩列,並不會佔滿12列,咱們須要定義新的grid-column-end,而且把他的值設爲 13. 這種方式比較麻煩,還有一種簡單的方式,grid-column: 1 / -1;,這樣不論在什麼屏幕尺寸下,它們都是佔滿整行的了。就像下面這樣:
.header, .footer {
grid-column: 1 / -1;
}複製代碼
grid-area: <name> | grid-row-start / grid-column-start / grid-row-end / grid-column-end
repeat()提供了一個緊湊的聲明方式。若是行列太多而且是規則的分佈,咱們能夠用函數來作網格線的排布。
grid-template-columns: repeat(3, 20px [col-start]) 5%;
// 等價於
grid-template-columns: 20px [col-start] 20px [col-start] 20px [col-start] 5%;
}複製代碼
minmax()至關於爲網格線間隔指定一個最小到最大的區間。若是min>max,這個區間就失效了,展現的是min。
fit-content()至關於 min('max-content', max('auto', argument));
flex-layout的佈局另一個問題是,在有大量內容繪製到頁面上、或者內容更改的狀況下,在2g或者網絡加載不穩定的時候,頁面是不穩定的。Flexbox vs Grid page layout。內容以流式從服務端獲取用戶能夠在頁面所有加載出來以前就看到內容,可是在flex佈局下會致使佈局的重排。正是由於flex自己就是一個彈性的佈局。但grid也不是徹底能夠避免佈局重排的問題——有前提:
必須讓你的網格劃分是能夠預先肯定的,好比是根據視窗寬高肯定的。若是是根據內容而定,那麼也是會崩壞的。複製代碼
下面的例子中,網格的列寬根據內容而定,所以也會根據內容而變。後面的aside並無定義在網格容器當中,是一個動態建立的元素。一旦被建立就會致使頁面重繪
.container {
display: grid;
grid-template-columns:
(foo) max-content,
(bar) min-content,
(hello) auto;
}
aside {
grid-column: 4;
}複製代碼
可是也不要放棄flex-layout,它是目前爲止最厲害的頁面佈局屬性,是時代召喚的結果,只是它並不適合佈局整個頁面框架。flex在響應式佈局中是很關鍵的,它是內容驅動型的佈局。不須要預先知道會有什麼內容,能夠設定元素如何分配剩餘的空間以及在空間不足的時候如何表現。顯得較爲強大的是一維佈局的能力,而grid優點在於二維佈局。這也是他們設計的初衷。
大概能夠設想,網格佈局被普遍支持以後會出現不少網格佈局內嵌flex的佈局情形。
subgrid暫時尚未瀏覽器支持,規範也是在改動之中的,因此先不介紹了。