CSS⽹格布局(Grid)完全教程
本⽂译⾃。由于译者⽔平有限,如有错误,请不吝指正。⽂中所有图的版权归原作者所有。
导语:CSS⽹格布局是⽬前CSS中可⽤的最强⼤的布局系统。它是⼆维系统,即可以处理⾏和列,不像flexbox只是⼀维系统。我们通过为⽗元素(变为grid container)和⼦元素(变为grid items)应⽤CSS规则来使⽤Grid布局。
⼀、介绍
CSS⽹格布局(亦称Grid)是⼀种基于⽹格的⼆维布局系统,主要致⼒于改变我们在页⾯中基于⽹格设计页⾯的⽅式。我们通常使⽤CSS 布局⽹页,但有时并不好⽤。⼀开始我们使⽤table,之后⽤浮动、定位和⾏内块级元素,但是所有这些⽅法都需要兼容,并且未实现⼀些重要功能(如垂直居中)。弹性盒⼦可以提供帮助,但它主要⾯向⼀维布局,不能处理复杂的两维布局(弹性盒⼦和⽹格布局其实配合得不错)。只要我们写⽹页,我们不得不考虑那些布局问题的hack实现,⽽⽹格布局是⾸个特地为解决这种问题⽽创造出来的模块。
我写这篇教程主要是因为受到两件事的影响。⼀个是Rachel Andrew的那本了不起的书——。这本书清晰透彻的介绍了Grid,也是本⽂的基础。我⾮常提倡你能买本读⼀下。另⼀个是Chris Coyier的,它指引
我使⽤flexbox来写布局。这篇⽂章帮助了很多⼈,从在google中搜索‘flexbox’该⽂排在第⼀位就能看出。你会看到两篇⽂章有很多相似之处,因为为什么我不借鉴好的东西中呢?
我写这篇教程的⽬的是介绍⽬前存在的最新版本中Grid的概念。我不会覆盖过时的IE语法,⽽且会随着版本的成熟定期更新教程。
⼆、基础和浏览器⽀持
⾸先我们要使⽤display:grid定义⼀个⽹格布局容器,⽤grid-template-columns和grid-template-rows设置列和⾏的尺⼨,然后按grid-
column和grid-row把⼦元素放进容器中。同flexbox类似,⽹格项的顺序并不重要,可以按任意顺序放置它们。这也使得使⽤媒体查询调整⽹格⾮常简单。想像⼀下,定义整个页⾯的布局,然后只需⼏⾏CSS代码就能将其重排为适应另⼀个尺⼨的屏幕。Grid真是有史以来引⼊的最强⼤的CSS模块。
截⾄2017年三⽉,Chrome(包括安卓端),Firefox、Safari(包括iOS端)和Opera在内的很多浏览器都⽀持原⽣的⽆前缀的CSS⽹格布局。IE10和11只部分⽀持,但使⽤的是过时的语法。Edge也已经宣告⽀持。
#桌⾯端
Chrome Opera Firefox IE Edge Safari
57445211*1610.1
#移动端、平板
iOS Safari Opera Mobile Opera Mini Android Android Chrome Android Firefox
10.3No No566155
除了微软,浏览器⼚商都在严格规范Grid直到规范成熟。这是⼀件好事,因为意味着我们不必学习多种语法。
在⽣产环境中使⽤Grid只是时间问题。是时候学它了。
三、重要术语
在我们正式学习Grid之前先了解⼀下其术语。由于这⾥的概念很类似,所以如果不先记住Grid规范定义的含义的话很容易弄混淆。但不⽤担⼼,术语并不是很多。
Grid Container
定义了display: grid的元素就成了⽹格容器。它是⽹格项的直接⽗元素。在下⾯的例⼦中,container就是Grid Container。
<div class="container">
<div class="item item-1"></div>
<div class="item item-2"></div>
<div class="item item-3"></div>
</div>
Grid Item
⽹格项是⽹格容器的⼦元素(如直接后代)。这⾥item元素是grid items,但是sub-item不是。
<div class="container">
<div class="item"></div>
<div class="item">
<p class="sub-item"></p>
</div>
<div class="item"></div>
</div>
Grid Line
⽹格线是组成⽹格结构的分割线。它们要么是垂直的(column grid lines),要么是⽔平的(row grid lines),来分割⾏或列。下⾯是⼀个列⽹格线的例⼦。
Grid Track
⽹格轨迹是两个相邻的⽹格线之间的空间。你可以把它想成⽹格的列或⾏。下⾯是⼀个在第⼆条和第三条⾏⽹格线的⽹格轨迹的例⼦。
Grid Cell
⽹格单元是由两个相邻的⾏⽹格线或列⽹格线围成的区域。它是⽹格的⼀个独⽴单元。下⾯是⼀个处于⾏⽹格线1、2和列⽹格线2、3之间的⽹格单元的例⼦。
Grid Area
⽹格区域是四条⽹格线围成的区域。⽹格区域可能由任意数量的⽹格单元构成。下⾯是⼀个处于⾏⽹格线1、3和列⽹格线1、3之间的⽹格区域的例⼦。
四、⽹格布局属性表
Grid Container的属性
该属性将元素定义为⽹格容器,建⽴⼀个⽹格格式上下⽂。
取值:
grid -⽣成块级⽹格
inline-grid -⽣成⾏级⽹格
subgrid -如果⽹格盒⼦本⾝是⼀个⽹格项(如嵌套⽹格布局),使⽤该值表⽰⾏列尺⼨来源于其⽗元素⽽⾮⾃⾝
.container{
display: grid | inline-grid | subgrid;
}
注意:column、float、clear、vertical-align对⽹格盒⼦没有影响。
⽤以空格分隔的列表值来定义⽹格的列和⾏。值表⽰轨迹⼤⼩,空格表⽰⽹格线。
取值:
<track-size> - 可以为长度、百分⽐或⽹格可⽤空间的⼀部分(单位是fr)
<line-name> - 可以取任意名称
.container{
grid-template-columns: <track-size> ... | <line-name> <track-size> ...;
grid-template-rows: <track-size> ... | <line-name> <track-size> ...;
}
例如:
当两个轨迹值之间留有空格的话,⽹格线会被⾃动赋值为⼀个数字名字:
.container{
flex布局对齐方式
grid-template-columns: 40px 50px auto 50px 40px;
grid-template-rows: 25% 100px auto;
}
不过也可以为⽹格线显⽰声明⼀个名字。注意下⾯声明名称的括号语法:
.
container{
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];
}
注意:每⼀⾏可能有不⽌⼀个名字。如下所⽰,第⼆⾏有row-1end和row2-start两个名字:
.container{
grid-template-rows: [row1-start] 25% [row1-end row2-start] 25% [row2-end];
}
如果定义中包含重复的部分,可以使⽤repeat()来简化书写:
.container{
grid-template-columns:repeat(3, 20px [col-start]) 5%;
}
这等同于:
.container{
grid-template-columns: 20px [col-start] 20px [col-start] 20px [col-start] 5%;
}
fr单允许我们将轨道尺⼨设置为⽹格容器的⼀部分。如下所⽰会将每个项⽬的尺⼨设置为容器的三分之⼀:
.container{
grid-template-columns: 1fr 1fr 1fr;
}
可⽤空间的计算是要除去⾮弹性项⽬的。如下所⽰,fr单元可⽤空间的⼤⼩不包括50px:
.container{
grid-template-columns: 1fr 50px 1fr 1fr;
}
通过引⽤由grid-area属性指定的⽹格区域的名字来定义⽹格模板。重复⽹格区域的名称会使其跨越那些单元格。⼀个句点表⽰⼀个空单元格。语法本⾝提供了对⽹格结构的可视化。
取值:
<grid-area-name> - grid-area属性指定的⽹格区域的名字
. - 句点表⽰⼀个空⽹格
none - 不定义任何⽹格区域
.container{
grid-template-areas:
"<grid-area-name> | . | none | ..."
"...";
}
举个例⼦:
.item-a{
grid-area: header;
}
.item-b{
grid-area: main;
}
.item-c{
grid-area: sidebar;
}
.item-d{
grid-area: footer;
}
.container{
grid-template-columns: 50px 50px 50px 50px;
grid-template-rows: auto;
grid-template-areas:
"header header header header"
"main main . sidebar"
"footer footer footer footer";
}
这会创建⼀个三⾏四列的⽹格。顶部单元格组成了header区域,中间⼀⾏由两个main区域、⼀个空区域、⼀个sidebar区域构成,最后⼀⾏是footer。
声明的每⼀⾏都要有相同数量的单元格。
您可以使⽤任意数量的相邻句点表⽰⼀个单独的空单元格。只要句点之间没有间隔它们就表⽰⼀个单独的单元。
要注意,该语法命名的是区域,⽽⾮⾏。不过使⽤该语法定义区域后,该区域两端都会⾃动获得命名。如,定义某个⽹格区域为foo,则该区域起始⾏和起始列的⽹格线将叫做foo-start,终⽌⾏和列将叫做foo-end。这也意味着⼀些⽹格线或有好⼏个名字。⽐如上例中最左边的⽹格线有三个名字:header-start、main-start和footer-start。
同时设置grid-template-rows、grid-template-columns、grid-template-areas的简写。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。