欢迎你 Grid Layout
517581
8年前
<p><img src="https://simg.open-open.com/show/d0840c270b3eae2fad25965477308e05.jpg"></p> <p><strong>Chrome</strong> 和 <strong>Firefox</strong> 都在最近的一个版本(Chrome 57 和 Firefox 52)正式对 grid layout 进行了支持,前端布局再次到达了一个新的里程碑。本文带大家回顾一下网页开发的布局方案发展历史,以及对 <strong>Grid Layout</strong> 的介绍和探索。</p> <h2>Web <strong>布局发展历程</strong></h2> <p>对于 Web 开发者来说,网页布局一直是个比较重要的问题。但实际上,在网页开发很长的一段时间当中,我们甚至没有一个比较完整的布局模块。总的来说 Web 布局经历了以下四个阶段:</p> <ol> <li>table,通过 Dreamweaver 拖拽表格或者手写 table 标签布局</li> <li>div、span、position、float,借助元素元素盒模型本身的特性以及 float position 等属性等进行布局</li> <li>flexbox ,革命性的突破,解决传统布局方案上的三大痛点 排列方向、对齐方式,自适应尺寸。是目前最为成熟和强大的布局方案。</li> <li>grid layout,二维布局模块,具有强大的内容尺寸和定位的能力,适合需要在两个维度上对齐内容的布局。</li> </ol> <p>笔者记得刚入行之初,无论大厂小厂,CSS 的布局问题几乎都是面试的一道必考题目,诸如 圣杯布局 、双飞翼布局和等高布局等等。因为它体现了你对 DIV + CSS 布局的掌握。当时作为一个萌新,为了准备面试,还把各种的居中方案做成 demo 在电脑里以备随时温习。记得那时候还有一个笑话:</p> <pre> <code class="language-css">44 年前我们就把人类送上了月球,但如今在 CSS 中我们仍然不能很好实现水平和垂直居中。</code></pre> <p>由此可见,在需要兼容很多低端浏览器(IE)的那个年代,布局问题带给了我们多大的烦恼。无论是使用 table 标签还是 position、float 等属性,在当时只是实现布局的一些 hack 技巧罢了。在更早前端还不叫前端的时候,网页设计师们甚至是用 DW 等编辑器通过拖拽表格来实现布局的。</p> <p>所以在很长一段时间,网页开发者们提出了各种各样的 hack,来满足页面的视觉效果。但是这些方法在很多响应式的场景中的表现依旧无法让人满意。</p> <p>后来,随着 Flexible Box 布局正式被各个浏览器厂商支持,网页布局技术迎来了一个转折点,当时感觉顿时间从巨大的痛苦中解脱了。 Flexible Box 是 W3C 标准委员会发布第一个布局模块,过程颇为艰辛,总共历经了三个语法版本才走到今天的 Candidate Recommendation 。让人欣慰的是,它是值得被等待的。因为 Flexible Box 给传统的网页布局解决了太多核心的问题,包括 <strong>排列方向</strong> 、 <strong>对齐方式,自适应尺寸</strong> 等等。</p> <p>而今天,Chrome 、Firefox 和 Safari 正式对 Grid Layout 布局模块的支持宣布着 Web 布局技术又迎来了新的转折点。这意味着我们现在可以直接在浏览器上使用 CSS Grid Layout 了。</p> <h2>Flexbox 还是 Grid Layout</h2> <p>在过去几年中,显然 CSS Flexbox 已被广泛使用, 浏览器支持 也非常好。Flexbox 几乎能解决大多数的场景。但我们知道 Flexbox 专注于轴内的空间分配,只能控制子元素在主轴上的排布规则。</p> <p style="text-align:center"><img src="https://simg.open-open.com/show/b6b44772948684dc22acfb30004b92f2.png"></p> <p>所以随着网站从简单文档演变成复杂的交互式应用程序,在面对需要同时控制子元素在水平和垂直的布局场景中,Flexbox 开始显得有心无力。</p> <p>CSS Grid Layout(又称“Grid”)就是为此而诞生的,Grid Layout 是一种基于二维网格的布局系统,旨在完全改变我们设计基于网格的用户界面的方式,弥补网页开发在二维布局能力上的缺陷。可能有读者对二维布局的术语上有些许陌生,下面我举个例子来展示它们的区别:</p> <p style="text-align:center"><img src="https://simg.open-open.com/show/abfca6471829feafcef513763ea4ed83.png"></p> <pre> <code class="language-css">.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; } }</code></pre> <p>如上面两个例子所示,Flex 提供的是单个方向上的空间分配和排列的能力,而 Grid Layout 则能够对子元素同时在两个方向上进行空间分配和排列对齐。</p> <p>因此,两个布局模块的作用是互为补充而非重叠的,相信两者在日后将相辅相成地成为前端开发中的布局利器。</p> <h2>Grid Layout 实践与应用场景</h2> <p>当我们得到一个工具时,自然会想到能用它来干什么。那我们首先来试试用它来解决一个古老而经典的问题—圣杯布局。</p> <h2>圣杯布局</h2> <p>圣杯布局的术语起源无从考究,笔者能找到的最早一篇文章是 2006 年 Matthew Levine 在他的一篇文章 In Search of the Holy Grail<a href="/misc/goto?guid=4959747374065650073" rel="nofollow,noindex"> </a> 里对其进行的解释。</p> <p>简单的说,圣杯布局是一个两边侧杆固定宽度和中间列为自适应宽度的三列布局。如下图所示:</p> <p style="text-align:center"><img src="https://simg.open-open.com/show/d9103f3ae7e293d256f92be19d2e4e85.jpg"></p> <pre> <code class="language-css"><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></code></pre> <p>上面这个例子可以看到用 CSS Grid 来实现一个完整的圣杯布局是极其简单的,核心代码其实只需要两行而已:</p> <pre> <code class="language-css">display: grid; grid: auto / 150px 1fr 180px;</code></pre> <p>显然,这类型的布局使用 Flexbox 是更加合适的,用 Grid Layout 有点杀鸡用牛刀的感觉。那么我们再来看一个复杂一点的。</p> <h2>照片墙布局</h2> <p style="text-align:center"><img src="https://simg.open-open.com/show/66535eb88f499c4dc4750e1badfbc341.jpg"></p> <p>在以往,我们实现这种照片墙布局一般直接使用绝对定位来实现,但这样做难以维护并且每一个块的位置调整都会影响到另一个,这是非常痛苦的,而且致命的是无法自适应宽度。而 Grid Layout 可以很好地帮助你实现此类布局,实现上面的例子的代码也非常简单:</p> <pre> <code class="language-css">// 此处只列出核心代码部分 .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; }</code></pre> <p>可以看到,除去样式代码部分,我们仅用不到 10 行的属性就完成了一个混乱编排的照片墙布局,并且他是自适应容器宽度的。这在以前是完全无法想象的。</p> <h2>总结</h2> <p>Grid Layout 具有接近 20 个属性之多,是一个强大的布局武器,在上述的例子中也仅仅用到了其中的几个属性而已。Grid Layout 像一道黎明之光,把前路照亮。笔者相信,在未来的各种复杂场景中,它还具有巨大的发挥空间。现在,我们是时候用起来了。</p> <p> </p> <p>来自:https://zhuanlan.zhihu.com/p/26259608</p> <p> </p>