歡迎你 Grid Layout
Chrome 和 Firefox 都在最近的一個版本(Chrome 57 和 Firefox 52)正式對 grid layout 進行了支持,前端布局再次到達了一個新的里程碑。本文帶大家回顧一下網頁開發的布局方案發展歷史,以及對 Grid Layout 的介紹和探索。
Web 布局發展歷程
對于 Web 開發者來說,網頁布局一直是個比較重要的問題。但實際上,在網頁開發很長的一段時間當中,我們甚至沒有一個比較完整的布局模塊。總的來說 Web 布局經歷了以下四個階段:
- table,通過 Dreamweaver 拖拽表格或者手寫 table 標簽布局
- div、span、position、float,借助元素元素盒模型本身的特性以及 float position 等屬性等進行布局
- flexbox ,革命性的突破,解決傳統布局方案上的三大痛點 排列方向、對齊方式,自適應尺寸。是目前最為成熟和強大的布局方案。
- grid layout,二維布局模塊,具有強大的內容尺寸和定位的能力,適合需要在兩個維度上對齊內容的布局。
筆者記得剛入行之初,無論大廠小廠,CSS 的布局問題幾乎都是面試的一道必考題目,諸如 圣杯布局 、雙飛翼布局和等高布局等等。因為它體現了你對 DIV + CSS 布局的掌握。當時作為一個萌新,為了準備面試,還把各種的居中方案做成 demo 在電腦里以備隨時溫習。記得那時候還有一個笑話:
44 年前我們就把人類送上了月球,但如今在 CSS 中我們仍然不能很好實現水平和垂直居中。
由此可見,在需要兼容很多低端瀏覽器(IE)的那個年代,布局問題帶給了我們多大的煩惱。無論是使用 table 標簽還是 position、float 等屬性,在當時只是實現布局的一些 hack 技巧罷了。在更早前端還不叫前端的時候,網頁設計師們甚至是用 DW 等編輯器通過拖拽表格來實現布局的。
所以在很長一段時間,網頁開發者們提出了各種各樣的 hack,來滿足頁面的視覺效果。但是這些方法在很多響應式的場景中的表現依舊無法讓人滿意。
后來,隨著 Flexible Box 布局正式被各個瀏覽器廠商支持,網頁布局技術迎來了一個轉折點,當時感覺頓時間從巨大的痛苦中解脫了。 Flexible Box 是 W3C 標準委員會發布第一個布局模塊,過程頗為艱辛,總共歷經了三個語法版本才走到今天的 Candidate Recommendation 。讓人欣慰的是,它是值得被等待的。因為 Flexible Box 給傳統的網頁布局解決了太多核心的問題,包括 排列方向 、 對齊方式,自適應尺寸 等等。
而今天,Chrome 、Firefox 和 Safari 正式對 Grid Layout 布局模塊的支持宣布著 Web 布局技術又迎來了新的轉折點。這意味著我們現在可以直接在瀏覽器上使用 CSS Grid Layout 了。
Flexbox 還是 Grid Layout
在過去幾年中,顯然 CSS Flexbox 已被廣泛使用, 瀏覽器支持 也非常好。Flexbox 幾乎能解決大多數的場景。但我們知道 Flexbox 專注于軸內的空間分配,只能控制子元素在主軸上的排布規則。
所以隨著網站從簡單文檔演變成復雜的交互式應用程序,在面對需要同時控制子元素在水平和垂直的布局場景中,Flexbox 開始顯得有心無力。
CSS Grid Layout(又稱“Grid”)就是為此而誕生的,Grid Layout 是一種基于二維網格的布局系統,旨在完全改變我們設計基于網格的用戶界面的方式,彌補網頁開發在二維布局能力上的缺陷。可能有讀者對二維布局的術語上有些許陌生,下面我舉個例子來展示它們的區別:
.item {
padding: 5px;
font-size: 14px;
box-sizing: border-box;
color: #929796;
background-color: #333;
border-radius: 5px;
&:nth-child(odd) {
background-color: #424242;
}
}
.container1 {
display: flex;
width: 630px;
flex-wrap: wrap;
.item {
width: 116px;
height: 40px;
margin: 5px;
}
.item-1, .item-2, .item-3 {
width: 200px;
}
}
.container2 {
display: grid;
grid-template-columns: repeat(5, 117px);
grid-auto-rows: minmax(40px, auto);
grid-column-gap: 10px;
grid-row-gap: 10px;
.item-4 {
grid-area: 1 / 4 / 3 / 6;
}
.item-5 {
grid-column-start: span 2;
}
}
如上面兩個例子所示,Flex 提供的是單個方向上的空間分配和排列的能力,而 Grid Layout 則能夠對子元素同時在兩個方向上進行空間分配和排列對齊。
因此,兩個布局模塊的作用是互為補充而非重疊的,相信兩者在日后將相輔相成地成為前端開發中的布局利器。
Grid Layout 實踐與應用場景
當我們得到一個工具時,自然會想到能用它來干什么。那我們首先來試試用它來解決一個古老而經典的問題—圣杯布局。
圣杯布局
圣杯布局的術語起源無從考究,筆者能找到的最早一篇文章是 2006 年 Matthew Levine 在他的一篇文章 In Search of the Holy Grail 里對其進行的解釋。
簡單的說,圣杯布局是一個兩邊側桿固定寬度和中間列為自適應寬度的三列布局。如下圖所示:
<body>
<header>Header</header>
<main>Main</main>
<nav>Nav</nav>
<aside>Aside</aside>
<footer>Footer</footer>
</body>
<style>
body {
display: grid;
grid: auto / 150px 1fr 180px;
}
header, footer {
background: bisque;
grid-column-end: span 4;
height: 80px;
}
main {
background: gold;
height: 300px;
}
nav {
background: coral;
}
aside {
background: orange;
}
</style>
上面這個例子可以看到用 CSS Grid 來實現一個完整的圣杯布局是極其簡單的,核心代碼其實只需要兩行而已:
display: grid;
grid: auto / 150px 1fr 180px;
顯然,這類型的布局使用 Flexbox 是更加合適的,用 Grid Layout 有點殺雞用牛刀的感覺。那么我們再來看一個復雜一點的。
照片墻布局
在以往,我們實現這種照片墻布局一般直接使用絕對定位來實現,但這樣做難以維護并且每一個塊的位置調整都會影響到另一個,這是非常痛苦的,而且致命的是無法自適應寬度。而 Grid Layout 可以很好地幫助你實現此類布局,實現上面的例子的代碼也非常簡單:
// 此處只列出核心代碼部分
.grid-layout {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
grid-gap: 10px;
grid-auto-rows: minmax(120px, auto);
grid-auto-flow: dense;
}
.grid-item {
background-color: rgba(4, 125, 200, 0.8);
&:nth-child(odd) {
background-color: rgba(44, 167, 249, 0.7);
}
}
.span-2 {
grid-column-end: span 2;
grid-row-end: span 2;
}
.span-3 {
grid-column-end: span 3;
grid-row-end: span 4;
}
可以看到,除去樣式代碼部分,我們僅用不到 10 行的屬性就完成了一個混亂編排的照片墻布局,并且他是自適應容器寬度的。這在以前是完全無法想象的。
總結
Grid Layout 具有接近 20 個屬性之多,是一個強大的布局武器,在上述的例子中也僅僅用到了其中的幾個屬性而已。Grid Layout 像一道黎明之光,把前路照亮。筆者相信,在未來的各種復雜場景中,它還具有巨大的發揮空間。現在,我們是時候用起來了。
來自:https://zhuanlan.zhihu.com/p/26259608