CSS Grid布局:独立源与网格的层叠顺序
最近一直在学习CSS Grid布局相关的知识与使用,虽然目前浏览器对其支持度还并不十分的友好,但我始终相信有一天,浏览器会支持,Web人员也迟早有一天能在自己的布局中使用上CSS Grid。前几天花了几节内容,介绍了CSS Grid布局中的概念、测试环境、创建单元格、合并单元、网格线创建和网格区域相关的内容。可以说这些内容都是CSS Grid布局最基础和最常用的相关知识,当然,除了这些之外,还会有其他相关的知识,今天要与大家一起探讨的就是有关于CSS Grid Layout中的独立源与网格层叠顺序。
##浏览器渲染原理
Web在浏览器中的渲染是非常复杂的,如果需要整明白浏览器是如何渲染Web页面,那需要对浏览器的渲染原理有足够的了解。如果你不了解浏览器是如何渲染Web页面,个人建议您先阅读Tali Garsiel和Paul Irish共同为大家写的一篇教程《浏览器的工作原理:新式网络浏览器幕后揭秘》。如果觉得这篇文章实在太长了,看得有点晕呼,你也可以阅读itwriter在博客园中发表的一篇读后感《浏览器的渲染原理简介》,帮助你更好的理解。
当然,有关于浏览器渲染原理并不是本文的重点,我们回到要讲的内容上来。先说说CSS Grid布局中的独立源。
##网格布局中的独立源
这里说的独立源,指的并不是源码。而是Web页面中的内容源。大家都知道,在Web中所说的源基本上指的是内容源,但对于我们来说并不关注他的内容是什么,而更关注的是他的HTML结构是什么?说得简单点,源指就是HTML结构。
在Web页面中,HTML结构是按照一种类似于树形结构的方向,根据从上到下,从前到后的顺序,依次出现。那么把这些HTML的标签元素称为源,而这些源的出现的顺序被称为内容流。
或许理论上说,有点晕呼,我们来看一个简单的示例,然后配合一些图片来说明这个问题,或许大家更易理解与接受。一图胜千言万语。
假设我们有一个简单的Web页面,其结构与内容如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>CSS Grid Layout</title>
<style>
.wrapper {
width: 600px;
margin: 0 auto;
}
.box {
background-color: #444;
color: #fff;
padding: 10px;
margin-bottom: 10px;
}
.ad1 {
background-color: orange;
}
.ad2 {
background-color: #f36;
}
</style>
</head>
<body>
<div class="wrapper">
<div class="box section1">Section content one</div>
<div class="box section2">Section content two</div>
<div class="box section3">Section content three</div>
<div class="box ad1">Advert!</div>
<div class="box ad2">Another lovely advert!</div>
</div>
</body>
</html>
这是一个非常简单的HTML页面的结构。针对上面的HTML结构,画出其对应的DOM树,从而更好的理解其内容流(也就是源)在Web页面中出现的先后顺序:
上图清晰的表述了HTML结构出现的顺序。在不对文档流做特殊处理情况下,其出现的顺序是从上到下,从前到后,如下图所示:
如果你需要实现下图的效果:
对比两者的效果,如果不修改HTML结构的情况之下,仅通过以前的CSS技术来实现上图的效果,对于Web前端人员来说是件痛苦的事情(Flexbox个性order值,或许能达到)。但在CSS Grid Layout中,这并不是问题。这也是今天要说的一个点:CSS Grid Layout中的独立源。
通过前面几篇文章大家应该了解到,在CSS Grid Layout中,HTML文档流(<body>
中的元素)出现的顺序并不重要,因为它一点不关注HTML中的结构顺序是什么?只要元素标签的父元素被声明了是网格容器:
.wrapper {
display: grid;
grid-template-columns: 600px;
grid-template-rows: auto ;
}
那么就可以根据设计的需要,通过grid-column
和grid-row
来决定.wrapper
内的子元素(也就是网格单元格,或网格区域)放在哪?就好比这个示例中所示一样,在.wrapper
容器内有五个div
元素,其中前三个div
放置的是页面关键内容(页面中更重要的信息),后面两个div
是用来放置广告内容(用户并不太关注)。而实际设计中,在一些平台中,希望广告内容穿插在其他内容中,这个时候Grid的魅力就展示出来了:
.wrapper {
width: 600px;
margin: 20px auto;
display: grid;
grid-template-columns: 600px;
grid-template-rows: auto ;
}
.section1 {
grid-row: 1 / 2;
}
.section2 {
grid-row: 3 / 4;
}
.section3 {
grid-row: 5 / 6;
}
.ad1 {
grid-row: 2 / 3;
}
.ad2 {
grid-row: 4 / 5;
}
效果如下:
试想一下,在移动终端,希望展先展示主内容,然后再展示广告内容,这个时候借助媒体查询就可以完美实现你需要的布局。
其实啰嗦这么多,唯一想说的就是:在CSS Grid Layout中具有独立的源(文档流),实现任何布局效果,完全不需要考虑文档流结构的先后顺序,只需要根据设计需求,调整网格单元格位置。
##网格分层
先来看一张滑块制作的示意图:
整个控件有六个部分:
- 下标(
lower-label
) - 上标(
upper-label
) - 下填充(
lower-fill
) - 上填充(
upper-fill
) - 滑块(
thumb
) - 滑块轨道(
track
)
Web前端人员拿到这样的一个效果基本上会考虑绝对 定位来布局,通过控制每个元素的宽度和高度来控制每个元素的大小,然后通过确定每个元素的顶端和工边的坐标来实现。那么在CSS Grid Layout中,Web前端人员可以通过Grid中相关的属性来实现。在这里只是想借助此图来说明,在CSS Grid Layout中任何元素都是其中的一个层。
##网格的层叠顺序
上面说过,在CSS Grid Layout中任何元素(单元格或网格区域)都是网格中的一个层,既然在一个网格中有很多个层存在,就会发现层与层之间的层叠。
在CSS Grid Layout中,网格单元格在交叉网格区域会发生重叠,或者在非交叉区域,使用margin
负值、position
定位也会发生重叠。而当网格单元格发生重叠时,可以通过z-index
属性来控制网格单元在Z轴的顺序。
如下面的示例所示,在容器.wrapper
中有A~F
六个.box
。其中.f
和.d
发现重叠,而且.e
通过margin-top
负值,致使.c~.f
都产生了重叠:
#####HTML
<div class="wrapper">
<div class="box a">A</div>
<div class="box b">B</div>
<div class="box c">C</div>
<div class="box d">D</div>
<div class="box e">E</div>
<div class="box f">F</div>
</div>
#####CSS
.wrapper {
display: grid;
grid-template-columns: repeat(5, (col) 100px (gutter) 10px) ;
grid-template-rows: repeat(3, (row) auto (gutter) 10px );
}
.a {
grid-column: col / span gutter 2;
grid-row: row ;
}
.b {
grid-column: col 3 / span gutter 3 ;
grid-row: row ;
}
.c {
grid-column: col ;
grid-row: row 2 ;
}
.d {
grid-column: col 2 / span gutter 3 ;
grid-row: row 2 ;
}
.e {
grid-column: col / span gutter 5;
grid-row: row 3;
background: rgb(136,36,136);
margin-top: -30px;
}
.f {
grid-column: col 3 / span gutter 3;
grid-row: row 2 ;
background-color: rgba(49,121,207, 0.5);
}
效果如下:
从效果图中可以看出,在CSS Grid Layout中Z轴的顺序(隐式的z-index
值)还是会根据文档流中结构出现的先后顺序来决定,越往后出现的元素,其z-index
的值越大。从这一点看,其并没有做太多的改变。
在CSS Grid Layout中同样可以通过显式的设置元素的z-index
值来改变元素在Z轴的顺序。在上例基础上做一定的修改:
.wrapper {
display: grid;
grid-template-columns: repeat(5, (col) 100px (gutter) 10px) ;
grid-template-rows: repeat(3, (row) auto (gutter) 10px );
}
.a {
grid-column: col / span gutter 2;
grid-row: row ;
}
.b {
grid-column: col 3 / span gutter 3 ;
grid-row: row ;
}
.c {
grid-column: col ;
grid-row: row 2 ;
z-index: 10;
}
.d {
grid-column: col 2 / span gutter 3 ;
grid-row: row 2 ;
}
.e {
grid-column: col / span gutter 5;
grid-row: row 3;
background: rgb(136,36,136);
margin-top: -30px;
z-index: 5;
}
.f {
grid-column: col 3 / span gutter 3;
grid-row: row 2 ;
background-color: rgba(49,121,207, 0.5);
z-index:4;
}
效果如下:
##总结
在这篇文章中主要介绍了CSS Grid Layout的文档流与元素在Z轴顺序相关的内容。从文章中简单的示例,可以得知,在CSS Grid Layout中,网格内的元素不受文档流渲染顺序所制,可以根据自己需求,独立控制元素在任何位置显示。当网格中单元格或者网格区域发生重叠时,同样可以根据z-index
值为控制其在Z轴的层级。