网页布局的未来—网格布局

近几年,Flexbox的出现,带来了巨大的轰动效应,它使CSS变得更加强大,给我们带来了更大的施展空间,并在几乎所有的浏览器中都得到了很好地支持,你没有理由不使用它。我们发现Flexbox在很多情况下对我们非常有帮助,但是它绝对不是一个构建整个布局的理想候选方案。我们更倾向于使用浮动或者内联元素来构建整体布局,但是这并不是浮动、内联元素被创建出来的初衷。但很遗憾CSS从来没有一个这样的内置功能,为了建立布局,我们没有选择,只能用这些Hack。好消息是CSS Grid Layout Model 是一个转折点,我们可以用它的一些基础功能就可以重建一些标准布局。目前,浏览器对网格布局的支持情况还不是很理想。唯一支持它的浏览器是Edage和最新的Internet Explorer 。幸运的是,我们可以在Google Chrome,FireFox ,Safari 上手动启用该功能,在Chrome上我们在导航栏输入chrome://flags切换到“启用实验性Web平台”标识并重启浏览器,FireFox上我们在导航栏输入about:config, 搜索 layout.css.grid.enabled 设置为true,Safari上我们需要下载 Safari Technology Preview 版本的浏览器,就可以使得浏览器支持网格布局。

当前浏览器兼容性

Chrome启用实验性Web平台

FireFox上开启网格布局

FireFox上开启网格布局

博客布局的重新设计

博客的布局是我们比较熟知的常用布局之一,有页眉(header),内容(content),侧边栏(sidebar),和页尾(footer)组成。我们接下来就围绕博客布局去介绍网格布局的基本概念。


博客布局

网格布局术语

  • 网格容器
  • 网格线
  • 网格轨道
  • 网格单元格
  • 网格区域

网格容器

网格容器为其中的内容建立新的网格格式化上下文( grid formatting context ),网格容器构成了内部网格项的边界

网格容器

网格线

网格线是水平和垂直分隔线。 我们将使用它们来构建网格轨道,网格单元格和网格区域。 他们有一个数字索引,或者我们也可以给他们一个特定的名字。

网格线

网格轨道

网格轨道是两条线之间的垂直或水平空间。


网格轨道

网格单元格

网格单元是在两个相邻的水平网格线和两个相邻的垂直网格线之间的项目。 它是我们可以把内容放入的最小单位。


网格单元格

网格区域

网格区域

网格布局的完整实现

现在我们用网格布局实现一下博客布局:

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

首先我们要设置displaygrid属性,对于其他的设置,我使用绝对值(pixels)作为长度单位,当然,也有更好的其他尝试(例如百分比、em、rem、vw和vh)。
属性 grid-template-columnsgrid-template-rows将生成网格轨道划分最外面的网格容器。 这两个属性的值既可以用固定值也可以使用auto。

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

定义网格的外观,看下面的代码,以及代码下面的解释图片:

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

我们也可以使用缩写:

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

上面这个例子很容易让你对即将到来的CSS网格布局充满憧憬,它真的是很好玩的东西,它入门很简单,通俗易懂,使人非常容易接受。但是更深入的接触之后会发现其实网格布局是很复杂的,甚至超过了Flexbox,它足足有17个新特性,并且围绕着我们编写CSS的方式介绍了许多新的概念,所以为了理解这个新的规范,弄清实战中它是怎样工作的,我们用它来创建一个圣杯布局。


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

圣杯布局是一种网页布局,由四部分组成:一个页眉,页脚和一个主要内容区域,有两个侧边,每边一个。布局遵循一下规则:

  • 两边带有固定宽度中间可以流动(fluid)
  • 中心列最先出现在标记中
  • 所有三列不管其中内容如何变化,都应该是相同的高度
  • 页脚应该总是在浏览器视窗的底部,即便内容不填满整个适口的宽度
  • 响应式布局,在较小的视口中,各部分要进行折叠,宽度100%显示

圣杯布局在CSS中,如果不用任何Hack是很难去实现的。

用网格布局的解决方案

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

分解代码

上面说过,CSS网格布局可以非常复杂,然后,我创建这个圣杯布局只用了17个新特性的4个:

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

我们用这些网格属性去实现圣杯布局布局可分为5个步骤。

1.定义网格

我们要做的第一件事情就是确认网格的区域,所以我们可以在创建网格时通过这个别名来引用它们。 我们使用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属性,我们可以用非常直观的方式指定网格的布局。 grid-template-areas属性接受一个空格分隔的字符串列表,每个字符串表示一行。 在每个字符串中,我们有一个空格分隔的网格区域列表,定义的每个网格区域占用一列。 因此,如果我们想要一个区域跨越两列,我们定义它两次。
在我们的圣杯布局中,我们有3列和3行。 页眉和页脚行横跨3列,而其他区域各跨1列。

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

使用这个标记,我们得到以下的结果:

定义网格
2.定义列宽

下一步,我们要定义的列的宽度。我们使用grid-template-columns属性定义列的宽度。该属性接受空格分格的宽度列表,网格中的每一列都有一个宽度。因为我们的布局有3列,我们可以指定3个宽度:

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

对于圣杯布局,我们希望2个侧边宽度为150px。

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

我们还希望中间列占据空间的其余部分。 我们可以通过使用新的fr单位来做到这一点。 此单位表示网格中剩余的自由空间的一小部分。 在我们的例子中,剩余自由空间是网格的当前宽度减去300px(两个边栏的宽度)。

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

设置网格列之后,这是布局的样子 :


定义列宽
3.定义行高

接下来,我们要定义行的高度。 类似于我们grid-template-columns定义列宽,我们使用 grid-template-rows定义行高。此属性还接受用空格分隔列表。虽然我们可以写在一行,但是我认为一行一行去写会更加直观清楚。

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

因此,我们的标题高度是100px,我们的页脚高度是30px,中间行(主要内容和两个侧边栏)占用.hg元素的剩余可用空间。

定义行高

4.固定页脚

在圣杯布局中,我们希望页脚始终位于视口的底部,即使页面上的内容不被充满一屏。 为了实现这一点,我们可以将.hg元素的最小高度设置为视口的高度。

.hg {
    min-height: 100vh;
}

因为我们指定中间行应该填充剩余的可用空间,它会伸展到填满屏幕。

固定页脚
5.设置响应式

最后,我们想让布局响应。 在较小的设备上,所有网格项目应该一个接一个地显示在一列中。 为此,我们需要重新定义之前定义的3个属性:
grid-template-areasgrid-template-columnsgrid-template-rows
首先,我们想要网格中的所有项目按照特定的顺序在一个列中:

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

接下来,我们想要所有项目占满网格宽度的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 */
    }
}
设置响应式

完成!在这里你可以看到它的演示和源码(你可能需要在浏览器中启用实验性的网络功能来查看它)

Grid Layout Module vs Flexbox

Flexbox适用于许多布局和很多“页面组件”元素,因为它们大多是基本线性的。 Grid适用于整体页面布局,以及非线性的复杂页面组件。
这两个可以任意组合,所以一旦广泛支持,我相信大多数页面将由一个外部网格的整体布局,混合嵌套flexbox和网格的页面组件,最后block/ inline-block /table布局在页面装饰文本和内容。

网格布局资源

上面讲的两种布局只使用了网格布局的4种属性,没有涵盖所有的网格布局概念和语法,如果对网格布局有兴趣,可以去下面的资源中更深入学习:

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的关于网格布局的最新信息和资源。 她为网格布局做了许多贡献。

总结

正如你所看到的,即将到来的CSS网格布局是强大的,因为它的代码简洁易懂,你很容易去设计和改变布局顺序。这些功能可以帮助我们永久改变网络开发中创建布局的方式,所以,我相信网格布局是CSS布局的未来!

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/

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,117评论 4 360
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,963评论 1 290
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 107,897评论 0 240
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,805评论 0 203
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,208评论 3 286
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,535评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,797评论 2 311
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,493评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,215评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,477评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,988评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,325评论 2 252
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,971评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,055评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,807评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,544评论 2 271
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,455评论 2 266

推荐阅读更多精彩内容

  • 简介 CSS Grid布局 (又名"网格"),是一个基于二维网格布局的系统,旨在改变我们基于网格设计的用户界面方式...
    咕咚咚bells阅读 2,423评论 0 4
  • 简介CSS网格布局(又称“网格”),是一种二维网格布局系统。CSS在处理网页布局方面一直做的不是很好。一开始我们用...
    _leonlee阅读 64,538评论 25 173
  • 前言 温馨提示:本文较长,图片较多,本来是想写一篇 CSS 布局方式的,但是奈何 CSS 布局方式种类太多并且实现...
    sunshine小小倩阅读 3,008评论 0 59
  • 原文地址:Getting to know CSS Grid Layout 原文作者:Chris Wright 译者...
    iKcamp阅读 3,709评论 0 13
  • 本篇文章共: 1188 个字,建议阅读:5分钟 每个人都在创造。 你所创造的,不仅仅是文字,也是属于你自己的品牌。...
    不二小兔子阅读 867评论 0 1