网页布局的前身今世
近年来,网页布局逐渐趋于统一化。从最初使用position+display+float来实现,到后来bootstrap3提出的栅格化布局,再到如今大厂经常考的Flex布局,每次改进的出发点都是如何减少布局时的工作量。但每一代都有自己的重大缺陷
传统布局 | BootStrap3 | BootStarp4 | Flex |
---|---|---|---|
相当精确,但工作量太大选择单位时,跨设备和缩放无法适应而选取百分比又不是很精确 | 为了兼容IE采用浮动方式实现z-index难以适配 | 采用了伸缩布局方式无法对局部使用 | 一维布局,纵向排列问题较大 |
可见,随着技术的进步,布局问题越来越少了。到Flex的时候,问题基本已经解决的差不多,只需要按照相同思路再设置一个垂直方向即可。在Chrome 57预览版发布时,W3C正式宣布开始支持Grid属性。这是第一个专门为解决布局问题而创建的 CSS 模块
Grid入门
一个典型的文档类网站布局,包括标题栏,主要内容区域,右侧边栏,左侧边栏等,这里以Docker Labs为例
如果我们简单划分一下结构,可以得到如下图片
每一个部分的内容比较简单,不做过多阐述。接下来的演示重点是排布方式。
之前我们学过 display: flex 的相关内容,针对这种单行大量插入SVG、icon有奇效,使用flex-grow实现div缩放 ,下面是核心代码
<style>#main{border:1px solid black; display:flex; background-color: #0d9cec; width: 100%; padding: 1%;}#main div:nth-of-type(1) {flex-grow: 1;font-size: 30px;}#main div:nth-of-type(2) {flex-grow: 1;font-size: 30px;}#main div:nth-of-type(3) {flex-grow: 3;}#main div:nth-of-type(4) {flex-grow: 1;font-size: 30px;}#main div:nth-of-type(5) {flex-grow: 1;font-size: 30px;}style>
但我们看下面三个内容区,如果使用Flex布局,有如下几个难点
自动缩放
多内容布局,自适应宽度
Flex是行级元素,不同大小会对应多个inline-flexbox,设置复杂
可能大家还会考虑通过设置Flex的方向和嵌套来解决问题,但对整体布局时会遇到早先网页布局的根本问题,又是一夜回到解放前。如果能同时满足横纵排列,则会极大的减少工作量,这就是二维网格布局——Grid
简单的划分一下,三个内容区组成了13的简单表格,而且左右两侧适应文本宽度,中间则是正文内容占据了大部分空间。我们首先将三个内容块放置到一个div中,并设置其属性display: grid ,开始建立网格结构
grid最主要的子属性是grid-template-columns、grid-template-rows,可以将一个矩形区域划分为几行几列。这里一个给大家展示一个简单的例子
<!--css-->#container{ display: grid; grid-template-columns: 50px 50px 50px 50px; grid-template-rows: 50px 50px;}<!----><div id="container"><div class="item item-1">1div><div class="item item-2">2div><div class="item item-3">3div><div class="item item-4">4div><div class="item item-5">5div><div class="item item-6">6div><div class="item item-7">7div><div class="item item-8">8div>div>
很明显,通过设置参数,我们将id为container的 div 区域分割为两行四列的表格,且每一部分都是正方形
但这个依旧不满足我们的需求,三个内容块的只知道有两个是自适应,一个是占据多数位置,并不知道它们各自的宽度,以px为单位会增加后期工作量
这里引入grid-template-columns、grid-template-rows 的两类参数,auto满足自适应行/列的大小,(n)fr满足比例设置。我们继续以上个模板为例,如果想要2、8自适应宽度,4、6比同行其他元素宽一倍,根据我们之前所说,grid是一个表格,而我所说的条件组成的图形很明显不是,因此要先把8个元素平均分到两个div 中。接着,我们可以根据要求,将1和3设置为1fr ,2设置为auto ,4设置为2fr ,同理可设置下一列
#container1{ display: grid; grid-template-columns: 1fr auto 1fr 2fr;}#container2{ display: grid; grid-template-columns: 1fr 2fr 1fr auto;}<div id="container1"><div class="item item-1">1div><div class="item item-2">2div><div class="item item-3">3div><div class="item item-4">4div>div><div id="container2"><div class="item item-5">5div><div class="item item-6">6div><div class="item item-7">7div><div class="item item-8">8div>div>
从结果来看,每一行设置都是先适应auto,之后根据比例再分配宽度。这是仅涉及grid-template-columns 的情况,如果再涉及列,又会如何呢? 我们将九宫格图,行列宽度适应依次改为auto 1fr 2fr 会是什么结果呢?是不是一个沿对角线依次放大的图形?
可能这个时候部分人有疑问了,为什么同样长宽都是1fr ,5显示的就不是一个正方形呢? 这里要明确一下,fr并不是一个长度单位,而是一个相对长度标识符,当
通过讲解,你是否想到那三个内容块如何排列呢?试着操作一下,下一期公布答案。
好吧,那么今天就到此为止。这是有关Grid的第一期,主要是讲了布局的发展历程和Grid入门,下一期我们继续挖掘Grid的深层知识。