Grid-layout不是为了取代flex-layout,它是flex的补充。grid擅长二维布局,flex擅长一维布局。他们须要各司其职。css
千呼万唤始出来的grid-layout终于在2017年3月开始支持获得了部分浏览器的支持。
css3
二维布局方式,能够按照行列方式排列内容。把页面划分为几块,指定不一样内容区块的大小、位置和层级。算法
有观点说grid很像table2.0,他们是有相同之处的。好比都是把元素排列成行和列。可是表格和grid的区别在于,表格是有内容结构的,不能很自由地在里面作布局。而grid内部元素能够自由设定位置,容许重叠和设定层级的样。segmentfault
网格容器为其内容创建新的网格格式化上下文,是内部网格项的边界。数组
水平垂直分割线,构建出网格轨道、网格单元格和网格区域。就像经纬,分割出南北半球、东西半球,热带、南北温带、南北寒带。网格线是有数字索引的,也能够本身取名字。经纬线都是有数字的,也能够命名,好比本初子午线、赤道。浏览器
网格内容块之间的水平或垂直的空间。滨盛、滨和、滨兴、滨安、滨康,江陵、江晖、江汉、江虹。(郊区的经典命名,摊手)bash
网格内容的单位区块,是能够放置内容的最小区块。好比用横纵三条网格线划分了页面,那么单元格就是九宫格中的一块网络
以网格线为界划定一块区域。本来网易和阿里巴巴都是占用一个单元格,如今都要扩建了,占用两个,两个加起来就是它们各自的网格区域。框架
在了解具体的属性以前,来一个最简单的例子ide
这样看会以为grid仍是颇有趣的,先分块,而后指定每一块的区域范围。块是能够重叠的。可是这只是开始,grid为咱们带来了17个新特性,在了解属性以前再来看一个例子,经典布局方案 —— 圣杯布局 holy grail layout。
你们能够迅速在脑子里码一下这个界面写个样式,不至于说复杂 但总之不简单吧。咱们看看grid是怎么作的
// key code
.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: 250px 1fr 300px;
grid-template-rows: 100px
1fr
80px;
min-height: 100vh;
}复制代码
步骤:
定义网格
grid-area: main;
grid-row-start: main;
grid-column-start: main;
grid-row-end: main;
grid-column-end: main;复制代码
设定单元格的高度和宽度
有一个css3的新单位,fr,在一串数值中出现的话表示根据比例分配某个方向上的剩余空间。设定行高的时候分行写是为了清晰一点。
设定固定位置的页脚
grid-template-columns: <track list>
,定义网格的行数、列数、网格大小。
有不少中形式,常见的是这么几种:
grid-template-columns: 100px 1fr;
grid-template-columns: [linename] 100px; // 定义网格线名字
grid-template-columns: [linename1] 100px [linename2 linename3]; // 一条网格线多个名字
grid-template-columns: minmax(100px, 1fr); // 最小100px, 最大满屏
grid-template-columns: fit-content(40%); // 指定最大值不超过屏宽40%
grid-template-columns: repeat(3, 200px); // 三列200px复制代码
// 给网格线指定名字
.box {
grid-template-columns: [first] 40px [line2] 50px [line3] auto [col4-start] 50px [five] 40px [end];
grid-template-rows: [row1-start] 25% [row1-end] 100px [third-line] auto [last-line];
}复制代码
定义网格区域,使用grid-area调用声明好的网格区域名称放置对应的网格项目。定义一个显式的网格区域。
定义网格之间的间距(不包括grid-item到容器边缘的间距)
定义网格子项的内容水平方向上的对齐方式,相似于flex-container的justify-content,只不过没有space-around和space-between
定义网格子项的内容垂直方向上的对齐方式,相似于flex-container的align-items
当出现网格容器容量大于网格总大小,好比每个网格子项都用了固定值的时候,指定网格在网格容器中和纵轴的对齐方式。后面三个属性值的区别在:
space-evenly: 始末两端的间距与网格间距相等
和justify-content对齐方向垂直,指定网格和横轴的对齐方式。
grid-auto-columns | grid-auto-rows做用是网格单元格不够的时候建立隐式的网格放置grid-item。看一个例子
咱们只定义了一个1×1的网格容器,box1放了进来,而后其余的三个怎么办呢?漏出来。box2接在box1后面渲染至屏幕右侧,box3和box4在底下渲染,高度仅仅为内容高度。
指定了grid-auto-columns: 200px; grid-auto-rows: 200px;
,至关于在容器中横纵都建立了更多的隐式的200*200的网格单元来盛放可能多出来的元素。
与之相关的还有另外一个属性:grid-auto-flow,在咱们没有设定这个属性的时候,多余的元素也按照从左到右从上到下的顺序排列,这个属性是控制自动布局算法的。
grid-auto-flow: row | column | row dense | column dense;
grid-row: grid-row-start / grid-row-end
grid-column: grid-column-start / grid-column-end | grid-column-start | span <value>复制代码
若是没有显式设置grid-column-end/grid-row-end,网格子项将默认跨越一个网格单元。此外,网格子项能够互相重叠,可使用z-index来控制他们的层叠顺序。
有一些元素,咱们想让它贯穿整个视口,好比像 header、footer,对于小屏幕,两列布局:
.header, .footer {
grid-column: 1 / 3;
}复制代码
不幸的是,当咱们换到大屏的时候,一行12列,这些元素将仅仅占满前两列,并不会占满12列,咱们须要定义新的grid-column-end,而且把他的值设为 13. 这种方式比较麻烦,还有一种简单的方式,grid-column: 1 / -1;,这样不论在什么屏幕尺寸下,它们都是占满整行的了。就像下面这样:
.header, .footer {
grid-column: 1 / -1;
}复制代码
grid-area: <name> | grid-row-start / grid-column-start / grid-row-end / grid-column-end
repeat()提供了一个紧凑的声明方式。若是行列太多而且是规则的分布,咱们能够用函数来作网格线的排布。
grid-template-columns: repeat(3, 20px [col-start]) 5%;
// 等价于
grid-template-columns: 20px [col-start] 20px [col-start] 20px [col-start] 5%;
}复制代码
minmax()至关于为网格线间隔指定一个最小到最大的区间。若是min>max,这个区间就失效了,展现的是min。
fit-content()至关于 min('max-content', max('auto', argument));
flex-layout的布局另一个问题是,在有大量内容绘制到页面上、或者内容更改的状况下,在2g或者网络加载不稳定的时候,页面是不稳定的。Flexbox vs Grid page layout。内容以流式从服务端获取用户能够在页面所有加载出来以前就看到内容,可是在flex布局下会致使布局的重排。正是由于flex自己就是一个弹性的布局。但grid也不是彻底能够避免布局重排的问题——有前提:
必须让你的网格划分是能够预先肯定的,好比是根据视窗宽高肯定的。若是是根据内容而定,那么也是会崩坏的。复制代码
下面的例子中,网格的列宽根据内容而定,所以也会根据内容而变。后面的aside并无定义在网格容器当中,是一个动态建立的元素。一旦被建立就会致使页面重绘
.container {
display: grid;
grid-template-columns:
(foo) max-content,
(bar) min-content,
(hello) auto;
}
aside {
grid-column: 4;
}复制代码
可是也不要放弃flex-layout,它是目前为止最厉害的页面布局属性,是时代召唤的结果,只是它并不适合布局整个页面框架。flex在响应式布局中是很关键的,它是内容驱动型的布局。不须要预先知道会有什么内容,能够设定元素如何分配剩余的空间以及在空间不足的时候如何表现。显得较为强大的是一维布局的能力,而grid优点在于二维布局。这也是他们设计的初衷。
大概能够设想,网格布局被普遍支持以后会出现不少网格布局内嵌flex的布局情形。
subgrid暂时尚未浏览器支持,规范也是在改动之中的,因此先不介绍了。