網(wǎng)頁(yè)布局的未來(lái)—網(wǎng)格布局

近幾年,F(xiàn)lexbox的出現(xiàn),帶來(lái)了巨大的轟動(dòng)效應(yīng),它使CSS變得更加強(qiáng)大,給我們帶來(lái)了更大的施展空間,并在幾乎所有的瀏覽器中都得到了很好地支持,你沒(méi)有理由不使用它。我們發(fā)現(xiàn)Flexbox在很多情況下對(duì)我們非常有幫助,但是它絕對(duì)不是一個(gè)構(gòu)建整個(gè)布局的理想候選方案。我們更傾向于使用浮動(dòng)或者內(nèi)聯(lián)元素來(lái)構(gòu)建整體布局,但是這并不是浮動(dòng)、內(nèi)聯(lián)元素被創(chuàng)建出來(lái)的初衷。但很遺憾CSS從來(lái)沒(méi)有一個(gè)這樣的內(nèi)置功能,為了建立布局,我們沒(méi)有選擇,只能用這些Hack。好消息是CSS Grid Layout Model 是一個(gè)轉(zhuǎn)折點(diǎn),我們可以用它的一些基礎(chǔ)功能就可以重建一些標(biāo)準(zhǔn)布局。目前,瀏覽器對(duì)網(wǎng)格布局的支持情況還不是很理想。唯一支持它的瀏覽器是Edage和最新的Internet Explorer 。幸運(yùn)的是,我們可以在Google Chrome,FireFox ,Safari 上手動(dòng)啟用該功能,在Chrome上我們?cè)趯?dǎo)航欄輸入chrome://flags切換到“啟用實(shí)驗(yàn)性Web平臺(tái)”標(biāo)識(shí)并重啟瀏覽器,F(xiàn)ireFox上我們?cè)趯?dǎo)航欄輸入about:config, 搜索 layout.css.grid.enabled 設(shè)置為true,Safari上我們需要下載 Safari Technology Preview 版本的瀏覽器,就可以使得瀏覽器支持網(wǎng)格布局。

當(dāng)前瀏覽器兼容性

Chrome啟用實(shí)驗(yàn)性Web平臺(tái)

FireFox上開(kāi)啟網(wǎng)格布局

FireFox上開(kāi)啟網(wǎng)格布局

博客布局的重新設(shè)計(jì)

博客的布局是我們比較熟知的常用布局之一,有頁(yè)眉(header),內(nèi)容(content),側(cè)邊欄(sidebar),和頁(yè)尾(footer)組成。我們接下來(lái)就圍繞博客布局去介紹網(wǎng)格布局的基本概念。


博客布局

網(wǎng)格布局術(shù)語(yǔ)

  • 網(wǎng)格容器
  • 網(wǎng)格線
  • 網(wǎng)格軌道
  • 網(wǎng)格單元格
  • 網(wǎng)格區(qū)域

網(wǎng)格容器

網(wǎng)格容器為其中的內(nèi)容建立新的網(wǎng)格格式化上下文( grid formatting context ),網(wǎng)格容器構(gòu)成了內(nèi)部網(wǎng)格項(xiàng)的邊界

網(wǎng)格容器

網(wǎng)格線

網(wǎng)格線是水平和垂直分隔線。 我們將使用它們來(lái)構(gòu)建網(wǎng)格軌道,網(wǎng)格單元格和網(wǎng)格區(qū)域。 他們有一個(gè)數(shù)字索引,或者我們也可以給他們一個(gè)特定的名字。

網(wǎng)格線

網(wǎng)格軌道

網(wǎng)格軌道是兩條線之間的垂直或水平空間。


網(wǎng)格軌道

網(wǎng)格單元格

網(wǎng)格單元是在兩個(gè)相鄰的水平網(wǎng)格線和兩個(gè)相鄰的垂直網(wǎng)格線之間的項(xiàng)目。 它是我們可以把內(nèi)容放入的最小單位。


網(wǎng)格單元格

網(wǎng)格區(qū)域

網(wǎng)格區(qū)域

網(wǎng)格布局的完整實(shí)現(xiàn)

現(xiàn)在我們用網(wǎng)格布局實(shí)現(xiàn)一下博客布局:

<div class="blog">
  <div class="header">Header</div>
  <div class="content">Content</div>
  <div class="sidebar">Sidebar</div>
  <div class="footer">Footer</div>
</div>

首先我們要設(shè)置displaygrid屬性,對(duì)于其他的設(shè)置,我使用絕對(duì)值(pixels)作為長(zhǎng)度單位,當(dāng)然,也有更好的其他嘗試(例如百分比、em、rem、vw和vh)。
屬性 grid-template-columnsgrid-template-rows將生成網(wǎng)格軌道劃分最外面的網(wǎng)格容器。 這兩個(gè)屬性的值既可以用固定值也可以使用auto。

.blog {
  display: grid;
  grid-template-columns: 400px 20px 180px;
  grid-template-rows: 100px 20px 210px 20px 100px;
}
Paste_Image.png

定義網(wǎng)格的外觀,看下面的代碼,以及代碼下面的解釋圖片:

.header {
  grid-row-start: 1;
  grid-row-end: 2;
  grid-column-start: 1;
  grid-column-end: 4;
}
.content {
  grid-row-start: 3;
  grid-row-end: 4;
  grid-column-start: 1;
  grid-column-end: 2;
}
.sidebar {
  grid-row-start: 3;
  grid-row-end: 4;
  grid-column-start: 3;
  grid-column-end: 4;
}
.footer {
  grid-row-start: 5;
  grid-row-end: 6;
  grid-column-start: 1;
  grid-column-end: 4;
}

我們也可以使用縮寫(xiě):

.header {
  grid-row: 1 /2;
  grid-column: 1 /4;
}
.content {
  grid-row: 3 /4;
  grid-column: 1 /2;
}
.sidebar {
  grid-row: 3 /4;
  grid-column: 3 /4;
}
.footer {
  grid-row: 5 / 6;
  grid-column: 1 / 4;
}

怎么樣才能更短呢?grid-area 遵循以下順序: grid-row-start , grid-column-start, grid-row-end, grid-column-end

.header {
  grid-area: 1 / 1 / 2 / 4;
}
.content {
  grid-area: 3 / 1 / 4 / 2;
}
.sidebar {
  grid-area: 3 / 3 / 4 / 4;
}
.footer {
  grid-area: 5 / 1 / 6 / 4;
}

最終代碼是這樣的:

.wrapper {
  display: grid;
  grid-template-columns: 400px 20px 180px;
  grid-template-rows: 100px 20px 210px 20px 100px;
}
.header {
  grid-area: 1 / 1 / 2 / 4;
}
.content {
  grid-area: 3 / 1 / 4 / 2;
}
.sidebar {
  grid-area: 3 / 3 / 4 / 4;
}
.footer {
  grid-area: 5 / 1 / 6 / 4;
}

上面這個(gè)例子很容易讓你對(duì)即將到來(lái)的CSS網(wǎng)格布局充滿(mǎn)憧憬,它真的是很好玩的東西,它入門(mén)很簡(jiǎn)單,通俗易懂,使人非常容易接受。但是更深入的接觸之后會(huì)發(fā)現(xiàn)其實(shí)網(wǎng)格布局是很復(fù)雜的,甚至超過(guò)了Flexbox,它足足有17個(gè)新特性,并且圍繞著我們編寫(xiě)CSS的方式介紹了許多新的概念,所以為了理解這個(gè)新的規(guī)范,弄清實(shí)戰(zhàn)中它是怎樣工作的,我們用它來(lái)創(chuàng)建一個(gè)圣杯布局。


什么是圣杯布局(Holy Grail Layout)

圣杯布局是一種網(wǎng)頁(yè)布局,由四部分組成:一個(gè)頁(yè)眉,頁(yè)腳和一個(gè)主要內(nèi)容區(qū)域,有兩個(gè)側(cè)邊,每邊一個(gè)。布局遵循一下規(guī)則:

  • 兩邊帶有固定寬度中間可以流動(dòng)(fluid)
  • 中心列最先出現(xiàn)在標(biāo)記中
  • 所有三列不管其中內(nèi)容如何變化,都應(yīng)該是相同的高度
  • 頁(yè)腳應(yīng)該總是在瀏覽器視窗的底部,即便內(nèi)容不填滿(mǎn)整個(gè)適口的寬度
  • 響應(yīng)式布局,在較小的視口中,各部分要進(jìn)行折疊,寬度100%顯示

圣杯布局在CSS中,如果不用任何Hack是很難去實(shí)現(xiàn)的。

用網(wǎng)格布局的解決方案

html

<body class="hg">  
  <header class="hg__header">Title</header>
  <main class="hg__main">Content</main>
  <aside class="hg__left">Menu</aside>
  <aside class="hg__right">Ads</aside>
  <footer class="hg__footer">Footer</footer>
</body>  

它的CSS只有31行!

.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: 150px 1fr 150px;
    grid-template-rows: 100px 
                        1fr
                        30px;
    min-height: 100vh;
}

@media screen and (max-width: 600px) {
    .hg {
        grid-template-areas: "header"
                             "navigation"
                             "main"
                             "ads"
                             "footer";
        grid-template-columns: 100%;
        grid-template-rows: 100px 
                            50px 
                            1fr
                            50px 
                            30px;
    }
}
Holy_Grail_CSS_Grid.gif

分解代碼

上面說(shuō)過(guò),CSS網(wǎng)格布局可以非常復(fù)雜,然后,我創(chuàng)建這個(gè)圣杯布局只用了17個(gè)新特性的4個(gè):

  • grid-area
  • grid-template-areas
  • grid-template-columns
  • grid-template-rows

我們用這些網(wǎng)格屬性去實(shí)現(xiàn)圣杯布局布局可分為5個(gè)步驟。

1.定義網(wǎng)格

我們要做的第一件事情就是確認(rèn)網(wǎng)格的區(qū)域,所以我們可以在創(chuàng)建網(wǎng)格時(shí)通過(guò)這個(gè)別名來(lái)引用它們。 我們使用grid-area屬性。

.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; }

然后,使用grid-template-areas屬性,我們可以用非常直觀的方式指定網(wǎng)格的布局。 grid-template-areas屬性接受一個(gè)空格分隔的字符串列表,每個(gè)字符串表示一行。 在每個(gè)字符串中,我們有一個(gè)空格分隔的網(wǎng)格區(qū)域列表,定義的每個(gè)網(wǎng)格區(qū)域占用一列。 因此,如果我們想要一個(gè)區(qū)域跨越兩列,我們定義它兩次。
在我們的圣杯布局中,我們有3列和3行。 頁(yè)眉和頁(yè)腳行橫跨3列,而其他區(qū)域各跨1列。

.hg {
    display: grid;
    grid-template-areas: "header header header"
                         "navigation main ads"
                         "footer footer footer";
}                         

使用這個(gè)標(biāo)記,我們得到以下的結(jié)果:

定義網(wǎng)格
2.定義列寬

下一步,我們要定義的列的寬度。我們使用grid-template-columns屬性定義列的寬度。該屬性接受空格分格的寬度列表,網(wǎng)格中的每一列都有一個(gè)寬度。因?yàn)槲覀兊牟季钟?列,我們可以指定3個(gè)寬度:

grid-template-columns: [column 1 width]  [column 2 width]  [column 3 width];  

對(duì)于圣杯布局,我們希望2個(gè)側(cè)邊寬度為150px。

.hg {
  grid-template-columns: 150px  [column 2 width] 150px;
}

我們還希望中間列占據(jù)空間的其余部分。 我們可以通過(guò)使用新的fr單位來(lái)做到這一點(diǎn)。 此單位表示網(wǎng)格中剩余的自由空間的一小部分。 在我們的例子中,剩余自由空間是網(wǎng)格的當(dāng)前寬度減去300px(兩個(gè)邊欄的寬度)。

.hg {
    grid-template-columns: 150px 1fr 150px;
}

設(shè)置網(wǎng)格列之后,這是布局的樣子 :


定義列寬
3.定義行高

接下來(lái),我們要定義行的高度。 類(lèi)似于我們grid-template-columns定義列寬,我們使用 grid-template-rows定義行高。此屬性還接受用空格分隔列表。雖然我們可以寫(xiě)在一行,但是我認(rèn)為一行一行去寫(xiě)會(huì)更加直觀清楚。

.hg {
    grid-template-rows: 100px 
                        1fr
                        30px;
}

因此,我們的標(biāo)題高度是100px,我們的頁(yè)腳高度是30px,中間行(主要內(nèi)容和兩個(gè)側(cè)邊欄)占用.hg元素的剩余可用空間。

定義行高

4.固定頁(yè)腳

在圣杯布局中,我們希望頁(yè)腳始終位于視口的底部,即使頁(yè)面上的內(nèi)容不被充滿(mǎn)一屏。 為了實(shí)現(xiàn)這一點(diǎn),我們可以將.hg元素的最小高度設(shè)置為視口的高度。

.hg {
    min-height: 100vh;
}

因?yàn)槲覀冎付ㄖ虚g行應(yīng)該填充剩余的可用空間,它會(huì)伸展到填滿(mǎn)屏幕。

固定頁(yè)腳
5.設(shè)置響應(yīng)式

最后,我們想讓布局響應(yīng)。 在較小的設(shè)備上,所有網(wǎng)格項(xiàng)目應(yīng)該一個(gè)接一個(gè)地顯示在一列中。 為此,我們需要重新定義之前定義的3個(gè)屬性:
grid-template-areasgrid-template-columnsgrid-template-rows
首先,我們想要網(wǎng)格中的所有項(xiàng)目按照特定的順序在一個(gè)列中:

@media screen and (max-width: 600px) {
    .hg {
        grid-template-areas: "header"
                             "navigation"
                             "main"
                             "ads"
                             "footer";
    }
}

接下來(lái),我們想要所有項(xiàng)目占滿(mǎn)網(wǎng)格寬度的100%:

@media screen and (max-width: 600px) {
    .hg {
        grid-template-columns: 100%;
    }
}

最后,我們需要重置每一行的高度。 除了主行之外,所有行限定它的高度:

@media screen and (max-width: 600px) {
    .hg {
        grid-template-rows: 100px /* Header */
                            50px /* Navigation */
                            1fr /* Main Content */
                            50px /* Ads */
                            30px; /* Footer */
    }
}
設(shè)置響應(yīng)式

完成!在這里你可以看到它的演示和源碼(你可能需要在瀏覽器中啟用實(shí)驗(yàn)性的網(wǎng)絡(luò)功能來(lái)查看它)

Grid Layout Module vs Flexbox

Flexbox適用于許多布局和很多“頁(yè)面組件”元素,因?yàn)樗鼈兇蠖嗍腔揪€性的。 Grid適用于整體頁(yè)面布局,以及非線性的復(fù)雜頁(yè)面組件。
這兩個(gè)可以任意組合,所以一旦廣泛支持,我相信大多數(shù)頁(yè)面將由一個(gè)外部網(wǎng)格的整體布局,混合嵌套flexbox和網(wǎng)格的頁(yè)面組件,最后block/ inline-block /table布局在頁(yè)面裝飾文本和內(nèi)容。

網(wǎng)格布局資源

上面講的兩種布局只使用了網(wǎng)格布局的4種屬性,沒(méi)有涵蓋所有的網(wǎng)格布局概念和語(yǔ)法,如果對(duì)網(wǎng)格布局有興趣,可以去下面的資源中更深入學(xué)習(xí):

CSS Grid Layout Module spec

A Complete Guide to CSS Grid Layout

CSS Grid Layout Examples
Grid by Example

The future of layout with CSS: Grid Layouts

還有Rachel Andrew的關(guān)于網(wǎng)格布局的最新信息和資源。 她為網(wǎng)格布局做了許多貢獻(xiàn)。

總結(jié)

正如你所看到的,即將到來(lái)的CSS網(wǎng)格布局是強(qiáng)大的,因?yàn)樗拇a簡(jiǎn)潔易懂,你很容易去設(shè)計(jì)和改變布局順序。這些功能可以幫助我們永久改變網(wǎng)絡(luò)開(kāi)發(fā)中創(chuàng)建布局的方式,所以,我相信網(wǎng)格布局是CSS布局的未來(lái)!

http://chris.house/blog/a-complete-guide-css-grid-layout/

https://en.wikipedia.org/wiki/Holy_Grail_(web_design)

https://bitsofco.de/holy-grail-layout-css-grid/

https://www.sitepoint.com/introduction-css-grid-layout-module/

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容

  • 簡(jiǎn)介 CSS Grid布局 (又名"網(wǎng)格"),是一個(gè)基于二維網(wǎng)格布局的系統(tǒng),旨在改變我們基于網(wǎng)格設(shè)計(jì)的用戶(hù)界面方式...
    咕咚咚bells閱讀 2,551評(píng)論 0 4
  • 簡(jiǎn)介CSS網(wǎng)格布局(又稱(chēng)“網(wǎng)格”),是一種二維網(wǎng)格布局系統(tǒng)。CSS在處理網(wǎng)頁(yè)布局方面一直做的不是很好。一開(kāi)始我們用...
    _leonlee閱讀 65,166評(píng)論 25 173
  • 前言 溫馨提示:本文較長(zhǎng),圖片較多,本來(lái)是想寫(xiě)一篇 CSS 布局方式的,但是奈何 CSS 布局方式種類(lèi)太多并且實(shí)現(xiàn)...
    sunshine小小倩閱讀 3,164評(píng)論 0 59
  • 原文地址:Getting to know CSS Grid Layout 原文作者:Chris Wright 譯者...
    iKcamp閱讀 3,798評(píng)論 0 13
  • 本篇文章共: 1188 個(gè)字,建議閱讀:5分鐘 每個(gè)人都在創(chuàng)造。 你所創(chuàng)造的,不僅僅是文字,也是屬于你自己的品牌。...
    不二小兔子閱讀 971評(píng)論 0 1