CSS躬行记(9)——网格布局

摘要:
网格布局也叫栅格布局,与表格布局类似,也依赖行和列。网格容器由display属性的两个特殊值所创建,由于它不是块级容器,因此其布局不受浮动和外边距塌陷的影响。网格线为网格容器划分不同的区域,注意,网格线的数量没有限制。网格区域由一个或多个相邻的网格单元组成的矩形区域,最大的网格区域会包含所有的网格单元。

网格布局(Grid Layout)也叫栅格布局,与表格布局类似,也依赖行和列。但与之不同的是,网格布局能直接控制HTML文档中元素的顺序、位置和大小等,而不用再借助辅助元素。

一、术语

下图展示了CSS规范中定义的网格。

CSS躬行记(9)——网格布局第1张

(1)网格容器(grid container)由display属性的两个特殊值(grid和inline-grid)所创建,由于它不是块级容器,因此其布局不受浮动和外边距塌陷的影响。

(2)网格项(grid item)也叫网格元素,是网格容器的子元素,注意,它的后代元素不是网格项,但它自身也能变为网格容器。

(3)网格线(grid line)为网格容器划分不同的区域,注意,网格线的数量没有限制。

(4)网格单元(grid cell)是由四条网格线限定的区域,其内部不会有其它的网格线。

(5)网格区域(grid area)由一个或多个相邻的网格单元组成的矩形区域,最大的网格区域会包含所有的网格单元。

(6)网格轨道(grid track)是由两条网格线夹住的区域,从容器的一边延伸到另一边,水平方向的叫网格行(grid row),垂直方向的叫网格列(grid column),它们的尺寸由网格线的位置决定。

二、行和列

grid-template-rows和grid-template-columns两个属性可以定义网格线的名称和网格轨道的尺寸,前者可声明行的数量,后者可声明列的数量。

在下面的示例中,将网格容器分成两行三列,其中第一条网格线距离容器左边界200px的位置,第二条网格线距离第一条网格线的偏移是容器宽度的一半,第三条网格线距离第二条30px的位置。

<style>div {display:grid;width:200px;height:100px;grid-template-rows:50px 50px;grid-template-columns:50px 50% 30px;
  }
</style>
<div>
  <section>1</section>
  <section>2</section>
  <section>3</section>
  <section>4</section>
  <section>5</section>
  <section>6</section>
</div>

下图的左侧是上述代码的效果,右侧中的虚线是生成的网格线,后文会反复使用这种格式的标注图。注意,网格线可以不与容器的边界接触,两个属性中的百分数参照的是网格容器的宽度或高度。

CSS躬行记(9)——网格布局第2张

如果要占满网格容器的横向空间,那么可以使用minmax()函数,如下所示。minmax(30px, 100%)表示该列所占的空间在30px和容器宽度之间,即不能小于30px并且不能大于容器宽度,效果如下图所示。

div {grid-template-columns:50px 50% minmax(30px, 100%);
}

CSS躬行记(9)——网格布局第3张

如果要为网格线命名,那么可以将名称放在值的恰当位置(例如名称在值之前,样式如下),并用方括号包裹。

div {grid-template-columns:[col-a] 50px [col-b] 50% [col-c] minmax(30px, 100%);
}

1)fr

在网格布局中,包含一个全新的fr单位,能将空间分成一定份数,弹性的分配给行或列,这个单位的作用类似于弹性盒中的flex-grow属性。在下面的示例中,将容器均分为3列,效果如下图所示。

div {grid-template-columns:1fr 1fr 1fr;
}

CSS躬行记(9)——网格布局第4张

注意,fr可与其它长度单位混合使用,其作用的是可用空间,即剩余空间。在下面的示例中,将第一列宽度固定,剩余的空间由两列均分,效果如下图所示。

div {grid-template-columns:30px 1fr 1fr;
}

CSS躬行记(9)——网格布局第5张

2)min-content和max-content

当网格轨道的尺寸与其内容有关时,可使用这两个关键字。min-content会占据内容所需的最小空间,例如将min-content应用于网格容器的第二列,样式如下,效果如下图所示,网格项中有大量的断行。

<style>div {grid-template-columns:30px min-content 1fr;
  }
</style>
<div>
  <section>1</section>
  <section>2 2 2</section>
  <section>3</section>
  <section>4</section>
  <section>5</section>
  <section>6</section>
</div>

CSS躬行记(9)——网格布局第6张

max-content的作用正好与min-content相反,它会占据内容所需的最大空间。将max-content也应用到上面的第二列,样式如下,效果如下图所示,网格项为了防止文本换行,会不断地扩大其宽度。

div {grid-template-columns:30px max-content 1fr;
}

CSS躬行记(9)——网格布局第7张

3)fit-content()

该函数的参数是一个长度值或百分数,能将占用空间指定成特定的值,它相当于下面等号右边的公式。

fit-content(argument) = min(max-content, max(min-content, argument))

先将接收的参数与min-content比较,得出较大值,再将该值与max-content比较,得到较小值。理解起来比较拗口,如果换成minmax()函数,含义就比较清晰了,与fit-content(argument)等价的公式如下。

minmax(min-content, max-content)

4)repeat()

该函数能为网格轨道声明重复的行或列,它的第一个参数是重复次数,第二个参数是轨道尺寸,例如将网格容器均分成三列,样式如下。

div {grid-template-columns:repeat(3, 1fr);
  /*等价于 */grid-template-columns:repeat(1fr, 1fr, 1fr);
}

注意,轨道尺寸不局限于一个,可以指定多个,样式如下,效果如下图所示。

div {grid-template-columns:repeat(2, 20px 1fr);
}

CSS躬行记(9)——网格布局第8张

三、网格项

通过起始和终止处的网格线的名称或编号可指定网格项的位置,其中列的编号从左到右依次递增,行的编号从上到下依次递增,如下图所示。

CSS躬行记(9)——网格布局第9张

在下面的示例中,将网格容器均分成三行四列,并且把第一个section元素指定到第二行第二列的位置,效果如下图所示。

<style>div {grid-template-rows:repeat(3, 1fr);grid-template-columns:repeat(4, 1fr);
  }.one {grid-row-start:2;grid-row-end:3;grid-column-start:2;grid-column-end:3;
  }
</style>
<div>
  <section class="one">1</section>
  <section>2</section>
  <section>3</section>
  <section>4</section>
  <section>5</section>
  <section>6</section>
  <section>7</section>
  <section>8</section>
  <section>9</section>
  <section>10</section>
</div>

CSS躬行记(9)——网格布局第10张

将下面的样式添加给第一个section元素,可以得到跨列的效果,如下图所示。

.two {grid-row-start:2;grid-row-end:3;grid-column-start:2;grid-column-end:4;
}

CSS躬行记(9)——网格布局第11张

网格线的编号支持负数,也就是以相反的方式计数,从后往前或从下往上,例如将第一个section元素放置在容器的右下角,样式如下,效果如下图所示。

.three {grid-row-start:-2;grid-row-end:-1;grid-column-start:-2;grid-column-end:-1;
}

CSS躬行记(9)——网格布局第12张

1)span

还有另一种方式可用来指定网格项的位置,即用span和正整数组合,表示要跨的网格轨道数目。在下面的样式中,“span 2”用于跨过两列。

.four {grid-row-start:2;grid-row-end:3;grid-column-start:2;grid-column-end:span 2;
}

当把span应用于grid-row-start或grid-column-start属性时,将会沿着网格开始的方向计数,样式如下,效果如下图所示。

.five {grid-row-start:2;grid-row-end:3;grid-column-start:span 2;grid-column-end:3;
}

CSS躬行记(9)——网格布局第13张

注意,span后面可以省略数字,默认是1,但不能跟零或负数。

2)简写属性

grid-row是grid-row-start和grid-row-end的简写属性,grid-column是grid-column-start和grid-column-end的简写属性。

grid-row和grid-column可分别将行和列的起止网格线声明在一行,并用斜杠(/)分隔,如下所示。

.six {grid-row:2 / 3;grid-column:2 / span 2;
}

注意,由于默认跨度是1,因此可以省略grid-row和grid-column斜杠后的数字,如下所示。

.seven {grid-row:2;grid-column:2;
}

grid-area是grid-row-start、grid-row-end、grid-column-start和grid-column-end的简写属性,也可用斜杠(/)将值分隔,如下所示。

.eight {grid-area:2 / 2 / 3 / span 2;
}

注意,网格线值的顺序是:起始行、起始列、终止行、终止列,围绕网格项逆时针排列。

3)重叠

当两个网格项发生重叠时,可通过z-index属性来决定谁在上,谁在下。例如为两个section元素分别添加下面的样式,效果如下图所示,第二个section元素覆盖了第一个section元素。

<style>.overlap1 {grid-row:1;grid-column:1 / span 2;
  }.overlap2 {grid-row:1;grid-column:2 / span 2;
  }
</style>
<div>
  <section class="overlap1">1</section>
  <section class="overlap2">2</section>
  <section>3</section>
  <section>4</section>
  <section>5</section>
  <section>6</section>
  <section>7</section>
  <section>8</section>
  <section>9</section>
  <section>10</section>
</div>

CSS躬行记(9)——网格布局第14张

当为第一个section元素添加z-index属性后(样式如下),就会覆盖第二个section元素,效果如下图所示。

.overlap1 {z-index:1;
}

CSS躬行记(9)——网格布局第15张

4)自动增加网格线

当网格项超出容器边界时,可通过grid-auto-rows和grid-auto-columns分别控制行和列的尺寸。

在下面的示例中,将网格容器分成两行三列,它的第七个超出边界的网格项的高度默认是内容的高度,即“height:auto”,效果如下图所示。

<style>div {grid-template-rows:50px 50px;grid-template-columns:repeat(3, 1fr);
  }
</style>
<div>
  <section>1</section>
  <section>2</section>
  <section>3</section>
  <section>4</section>
  <section>5</section>
  <section>6</section>
  <section>7</section>
</div>

CSS躬行记(9)——网格布局第16张

当为网格容器添加grid-auto-rows属性后,就能改变网格项的高度,如下所示,效果如下图所示。

div {grid-auto-rows:50px;
}

CSS躬行记(9)——网格布局第17张

grid-auto-columns的用法与之类似,但修改的是超出边界的网格项的宽度。在下图中,左侧是默认超出时的宽度,即内容的宽度(auto);右侧是为容器添加下面样式后的宽度。

div {grid-auto-flow:column;grid-auto-columns:50px;
}

CSS躬行记(9)——网格布局第18张

注意,grid-auto-flow是一个网格流属性,可让网格项按列排序,后文第五节会重点讲解。

四、网格区域

通过grid-template-areas属性能够以可视化的方式声明网格布局,其值是用空格或换行符分隔的字符串列表,每段字符串又是以空格分隔的自定义标识符,如下所示。

div {grid-template-areas:"a b b" 
              "a . c";
}

每个标识符表示一个网格单元,注意,组合在一起的形状必须得是矩形。当只需要占位时,可以使用点号(.)创建匿名单元。

为了将网格项与网格区域关联,需要使用grid-area属性。通过它来引用命名好的网格区域,如下所示,grid-area的属性值就是grid-template-areas属性中的标识符,效果如下图所示。

<style>.a {grid-area:a;
  }.b {grid-area:b;
  }.c {grid-area:c;
  }
</style>
<div>
  <section class="a">a</section>
  <section class="b">b</section>
  <section class="c">c</section>
</div>

CSS躬行记(9)——网格布局第19张

五、网格流

网格流可由grid-auto-flow属性控制,它分为两种填充方式:逐行和逐列,并且两者都可通过稠密模式更高效地占用网格单元。

在下面的示例中,第一个div元素中的网格项会先填满一行再换到下一行,效果如图5-57的左侧;第二个div元素中的网格项会先填满一列再换到下一列,效果如下图的右侧。

<style>.row {grid-auto-flow:row;
  }.column {grid-auto-flow:column;
  }
</style>
<div class="row">
  <section>1</section>
  <section>2</section>
  <section>3</section>
  <section>4</section>
  <section>5</section>
  <section>6</section>
</div>
<div class="column">
  <section>1</section>
  <section>2</section>
  <section>3</section>
  <section>4</section>
  <section>5</section>
  <section>6</section>
</div>

CSS躬行记(9)——网格布局第20张

grid-auto-flow属性默认是稀疏模式,而稠密模式会尽力找出最前面的空位置。假设网格容器包含三个网格项,其中有两个会占用两个网格单元,样式如下,效果如下图所示,第一个网格项之后的网格单元闲置着。

<style>.across {grid-column:auto / span 2;
  }
</style>
<div class="row">
  <section class="across">1</section>
  <section class="across">2</section>
  <section>3</section>
</div>

CSS躬行记(9)——网格布局第21张

当为网格容器的grid-auto-flow属性添加dense后,就能触发稠密模式,得到的效果如下图所示,第三个网格项会移动到第一个之后。

.row {grid-auto-flow:row dense;
}

CSS躬行记(9)——网格布局第22张

六、间距

间距(gutter)也叫空距或栏距,用于控制两个网格轨道之间的距离,类似于将网格线加粗,使其具有宽度。

间距可由grid-row-gap和grid-column-gap两个属性设定,但要注意,现在这两个属性已改名成row-gap和column-gap,它们相当于表格样式中的border-spacing属性。在下面的示例中,为网格容器添加了两个方向的间距,效果如下图所示。

div {row-gap:10px;column-gap:20px;
}

CSS躬行记(9)——网格布局第23张

grid-gap是一个简写属性,可将行和列的间距组合在一起定义,下面样式的效果与上图一样。注意,该属性现已改名成gap。

div {gap:10px 20px;
}

顺便说一句,CSS规范提供了一个简写属性:grid,可将上述grid-template-rows、grid-auto-rows、row-gap等属性组合在一起声明。

七、对齐方式

网格布局中的对齐属性与弹性盒中的类似,也是使用下表中的相关属性。

属性作用
justify-self控制一个网格项的水平对齐
align-self控制一个网格项的垂直对齐
justify-items控制网格容器中的所有网格项的水平对齐
align-items控制网格容器中的所有网格项的垂直对齐
justify-content控制网格轨道的水平对齐
align-content控制网格轨道的垂直对齐

1)对齐网格项

justify-self和align-self两个属性适用于单个网格项,它们的默认值都是stretch,其它可选的关键字包括start、end和center等。

假设有一个两行三列的网格容器,为它的四个网格项分别添加四个不同关键字的justify-self属性,效果如下图所示。

<style>div {display:grid;grid-template-rows:repeat(2, 1fr);grid-template-columns:repeat(3, 1fr);
  }.justify-self-start {justify-self:start;
  }.justify-self-end {justify-self:end;
  }.justify-self-center {justify-self:center;
  }.justify-self-stretch {justify-self:stretch;
  }
</style>
<div>
  <section class="justify-self-start">start</section>
  <section class="justify-self-center">center</section>
  <section class="justify-self-end">end</section>
  <section class="justify-self-stretch">stretch</section>
</div>

CSS躬行记(9)——网格布局第24张

将这四个关键字赋给align-self属性,再应用到另一个两行三列的网格容器中,得到的效果如下图所示。

CSS躬行记(9)——网格布局第25张

justify-items和align-items两个属性适用于网格容器,它们的默认值也是stretch,可选的关键字与之前的两个属性类似,下面的样式在为之前的div元素(网格容器)添加justify-items属性。

div {justify-items:start;
}

2)对齐网格轨道

justify-content和align-content两个属性适用于网格容器,可用的关键字包括start、end、center、space-between和space-around等。

下图展示了这五个关键字赋给justify-content属性后,再分别应用于网格容器的效果。

CSS躬行记(9)——网格布局第26张

下图展示了这五个关键字赋给align-content属性后,再分别应用于网格容器的效果。

CSS躬行记(9)——网格布局第27张

八、排序

在网格布局中,也可以像弹性盒那样使用order属性调整网格项的顺序。注意,order属性作用于网格项,其值是一个整数,包括零和负数。在下面的示例中,将第一个和第三个section元素调换了次序,效果如下图所示。

<style>.first {order:1;
  }.second {order:2;
  }.third {order:3;
  }
</style>
<div>
  <section class="third">1</section>
  <section class="second">2</section>
  <section class="first">3</section>
</div>

CSS躬行记(9)——网格布局第28张

免责声明:文章转载自《CSS躬行记(9)——网格布局》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇python去掉headers中的某个参数【转】oracle之函数与过程下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

前端UI框架小汇总

前言: 近期,小弟根据GitHub、前端社区、掘金等平台对当前流行的前端UI框架的进行了小小的整理和汇总(ps:前端UI框架的应用是通过GitHub star数,社区热度和使用范围等进行的粗略的汇总【不分先后】)。希望对寻找UI框架的小伙伴们提供点帮助。 以下对前端UI框架的移动端、PC端和混合APP的应用进行了列举。 移动端UI框架 Mint UI(饿了...

HTML与CSS布局技巧

一、使用$标识原生DOM元素 let $white = document.querySelector('.white') 二、要使用top,left等定位属性 要先将该元素设置position属性,absolute或者relative等 三、十种选择器 三类基础选择器: ID选择器; class选择器; 标签选择器,tag; 以下为延伸的选择器:...

从零开始配置TypeScript + React + React-Router + Redux + Webpack开发环境

转载请注明出处! 说在前面的话: 1、为什么不使用现成的脚手架?脚手架配置的东西太多太重了,一股脑全塞给你,我只想先用一些我能懂的库和插件,然后慢慢的添加其他的。而且自己从零开始配置也能学到更多的东西不是么。 2、教程只配置了开发环境,并没有配置生产环境。 3、教程针对人群是有过React + Redux经验,并且想在新项目中使用TypeScript的人(...

css盒子模型的宽度问题

最近看css权威指南的时候,发现一个之前特别不清楚的概念——宽度。 每个块级元素都有一个元素框,元素框内包括了元素内容,元素内边距,元素边框,元素外边距。 所以元素框的宽度=元素内容宽度+元素内边距+元素边框+元素外边距。 也就是他父元素的内容宽度。 那么我们常说的width就是元素框的宽度吗? 答案是否定的。我们常说的width属性值在css中被定义为从...

CSS文本部分之字体样式[1]

1. 字体系列 [通用字体系列] 1. serif字体:带衬线字体,如Georiga、Times等 2. sans-serif字体:不带衬线字体,包括Arial、Geneva等 3. Monospace字体:等宽字体,包括Courier等 4. Cursive字体:手写字体,包括Author等 5. Fanstasy字体:无法归类,包括Western等...

JSX设置CSS样式详解

JSX设置CSS样式详解 1. 使用className设置样式(CSS的其他选择器也是同理) (1)定义一个CSS文件style.css,和普通CSS一样定义class选择器 .sty1{//和普通CSS一样定义class选择器 background-color: red; color: white; font-size: 40px...