Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

栅格布局 #15

Open
xiongshj opened this issue Aug 16, 2019 · 0 comments
Open

栅格布局 #15

xiongshj opened this issue Aug 16, 2019 · 0 comments

Comments

@xiongshj
Copy link
Owner

栅格布局

这是学习《CSS 权威指南》第 13 章的笔记。

创建栅格容器

栅格有两种:常规栅格和行内栅格。这两种栅格使用 display 属性的特殊值创建:grid 和 inline-grid。前者生成块级框,后者生成行内框。

栅格容器的子元素是栅格元素。子元素的子元素不是栅格元素。

栅格容器的外边距不与其后代的外边距折叠。

有些 CSS 属性和功能不能用在栅格容器和栅格元素上,如下:

(1)栅格容器上的所有 column 属性(例如 column-count、columns 等)都被忽略。

(2)栅格容器没有 ::first-line 和 ::first-letter 伪元素,如果使用,将被忽略。

(3)栅格元素(而非栅格容器)上的 float 和 clear 属性将被忽略。

(4)vertical-align 属性对栅格元素不起作用。

如果为栅格容器声明的 display 值是 inline-grid,而目标元素是浮动的或绝对定位的,那么 display 的计算值将变为 grid(取代 inline-grid)。

基本的栅格术语

栅格元素是在栅格格式化上下文中参与栅格布局的东西。这通常是栅格容器的子元素,但也可以是元素内容中的匿名文本(即不在元素中的文本)。

栅格轨道(grid track)指两条相邻的栅格线之间夹住的整个区域,从栅格容器的一边延伸到对边,即栅格列或栅格行。栅格轨道的尺寸由栅格线的位置决定。

栅格单元(grid cell)指四条栅格线限定的区域,内部没有其他栅格线贯穿,类似于单元格。这是栅格布局中区域的最小单位。栅格单元不能直接使用 CSS 栅格属性处理,即没有属性能把一个栅格元素放在指定的栅格单元里。

栅格区域(grid area)指任何四条栅格线限定的矩形区域,由一个或多个栅格单元构成。最小的栅格单元区域是一个栅格单元,最大的栅格区域是栅格中所有的栅格单元。栅格区域能使用 CSS 属性直接处理,定义好栅格区域后即可在其中放置栅格元素。

上述栅格术语演示图

栅格容器属性

grid-template-rows 和 grid-template-columns 属性

grid-template-rows,grid-template-columns 使用这两个属性可以大致定义栅格模板(grid template,CSS 规范称之为 explicit grid,显式栅格)中的栅格线。栅格中的一切都依赖栅格线。这两个属性的初始值是 none,适用于栅格容器。

(1)定义三个宽度固定的栅格列:

#grid {
  display: grid;
  grid-template-columns: 200px 50% 100px; 
}

(2)为栅格线命名:

#grid {
  display: grid;
  grid-template-columns: [start col-a] 200px [col-b] 50% [col-c] 100px [stop end last];
  grid-template-rows: [start masthead] 3em [content] 80% [footer] 2em [stop end];
}

(3)minmax(a, b) 函数设定一个长度范围,表示长度就在这个范围之中。

#grid {
  display: grid;
  grid-template-rows: [start masthead] 3em [content] minmax(3em, 100%) [footer] 2em [stop end];
}

minmax() 表达式的最小值部分不允许使用 fr 单位。

如果最小值比最大值大,那么整个值将替换为最小值。因此,minmax(500px, 200px) 将视为只有 500px 一个值。

(4)轨道的高度(或宽度)还可以使用 calc() 计算。

#grid {
  display: grid;
  grid-template-rows: [start masthead] 3em [content] calc(100% - 5em) [footer] 2em [stop end];
}

(5)份数单位:如果想把余下的空间分成一定份数,分配给各栏,可以使用 fr 单位。

#grid {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr 1fr;
}

(6)min-content 意思是“尽量少占据空间,够显示内容即可”。max-content 意思是“占据内容所需的最大空间”。auto 关键字表示由浏览器自行决定长度。

(7)fit-content

fit-content() 函数的参数为一个长度或一个百分数。

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

这个公式的意思是:先确定 min-content 和指定的参数哪个大,然后拿较大的那个值与 max-concont 相比,找出较小的。

(8)repeat() 简化重复的值

#grid {
  display: grid;
  grid-template-columns: repeat(10, 5em);
  grid-template-columns: repeat(3, 2em 1fr 1fr);
  grid-template-columns: repeat(3, 2em 1fr 1fr) 2em;
  grid-template-columns: repeat(4, 10px [col-start] 250px [col-end] 10px);
}

(9)auto-fill 关键字

#grid {
  display: grid;
  grid-template-rows: repeat(auto-fill, [top] 5em [bottom]);
}

上述代码会每隔 5em 放置一条栅格线,直到没有空间为止。

自动重复的局限是,只能有一个可选的栅格线名称、一个尺寸固定的轨道和另一个可选的栅格线名称。

(10)如果使用 auto-fit,没有栅格元素的轨道将被剔除。除此之外,auto-fit 的行为与 auto-fill 一样。

grid-template-columns: repeat(auto-fit, 20em);

grid-template-areas 属性

栅格区域可以使用 grid-template-areas 指定,这个属性的初始值是 none,适用于栅格容器。

#grid {
  display: grid;
  grid-template-areas: "h h h h"
                       "l c c r"
                       "l f f f";
}

每个字符串(放在一对双引号中)定义栅格的一行。

浏览器把名称相同的相邻单元合并为一个区域,不过得到的形状必须是矩形。

定义好栅格区域之后,接下来要使用 grid-template-columns 和 grid-template-rows 定义栅格轨道的尺寸。例如:

#grid {
  display: grid;
  grid-template-areas: "header header header header"
                       "left   ...    ...    right"
                       "footer footer footer footer";
  grid-template-columns: 1fr 20em 20em 1fr;
  grid-template-rows: 40px 10em 3em;
}

grid-auto-flow 属性

栅格流主要分为两种模式,即行优先和列优先。栅格流通过 grid-auto-flow 属性设置。这个属性的初始值是 row,适用于栅格容器。

#grid {
  display: grid;
  width: 45em;
  height: 8em;
  grid-auto-flow: row;
}

如果想让栅格元素尽量紧靠,而不管顺序会受到什么影响,只需要在 grid-auto-flow 的值里面加上关键字 dense。

grid-auto-flow: dense column;

grid-auto-rows 和 grid-auto-columns 属性

默认情况下,自动增加的行是所需的最小尺寸。如果想指定新增的行的大小,可以使用 grid-auto-rows 和 grid-auto-columns 这两个属性,它们的初始值是 auto,适用于栅格容器。

.grid {
  display: grid;
  grid-template-rows: 80px 80px;
  grid-template-columns: 80px 80px;
}

#g1 {
  grid-auto-rows: 80px;
}

上面代码的效果演示图

grid 简写属性

grid 属性是 grid-template-rows、grid-template-columns、grid-template-areas、grid-auto-flow、grid-auto-rows、grid-auto-columns 这六个属性的合并简写形式。适用于栅格容器。

grid 属性的作用是以简洁的语法定义栅格模板,或者设定栅格流,并为自动增加到轨道设定尺寸。但是二者不能同时设置。

未定义的值都重置为默认值,这与其他简写属性是一致的。

#grid {
  display: grid;
  grid: "header header header header" 3em
        ". content sidebar ." 1fr
        "footer footer footer footer" 5em / 
        2em 3fr minmax(10em, 1fr) 2em;

  /* 下面的规则与上面的 grid 声明是等效的 */
  grid-template-areas: "header header header header"
                       ". content sidebar ."
                       "footer footer footer footer";
  grid-template-rows: 3em 1fr 5em;
  grid-template-columns: 2em 3fr minmax(10em, 1fr) 2em;

  /* 把字符串去掉 */
  grid: 3em 1fr 5em / 2em 3fr minmax(10em, 1fr) 2em;
}

grid 属性的另一个用法是融合 grid-auto-flow、grid-auto-rows 和 grid-auto-columns。下面两个规则是等效的:

#layout {
  grid-auto-flow: dense rows;
  grid-auto-rows: 2em;
  grid-auto-columns: minmax(1em, 3em);
}

#layout {
  grid: dense rows 2em / minmax(1em, 3em);
}

grid-row-gap 和 grid-column-gap 属性

栏距是两个栅格轨道之间的间隔。这两个属性的初始值是 0,适用于栅格容器。

grid-row-gap: 15px;
grid-column-gap: 1em;

这两个属性现已改名为 row-gap 和 column-gap。

grid-gap 属性

grid-gap 属性把行和列的栏距合在一起设定。初始值是 0 0,适用于栅格容器。

grid-gap: 12px 2em;

这个属性现已改名为 gap。

justify-items 和 align-items 属性

justify-items 和 align-items 属性用来横向对齐或纵向对齐全部元素,适用于栅格容器。

#grid {
  display: grid;
  align-items: center;
  justify-items: center;
}

上面的代码让栅格中的所有栅格元素在各自的栅格区域里居中对齐:效果演示图

justify-content 和 align-content 属性

使用 justify-content 和 align-content 属性以一定的方式分布栅格元素,抑或横向对齐或纵向对齐整个栅格。

链接中第 65-68 个图是这两个属性的可选值(部分)演示。

栅格元素属性

grid-row-start、grid-row-end、grid-column-start 和 grid-column-end 属性

栅格元素的位置是可以指定的,具体方法是指定栅格元素的四个边框,分别定位在哪根栅格线上。

这四个属性的初始值都是 auto,适用于栅格元素和绝对定位元素(前提是容纳块为栅格容器)。

.grid {
  display: grid;
  width: 50em;
  grid-template-rows: repeat(5, 5em);
  grid-template-columns: repeat(10, 5em);
}

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

.two {
  grid-row-start: 1;
  grid-row-end: 3;
  grid-column-start: 5;
  grid-column-end: 10;
}

.three {
  grid-row-start: 4;
  grid-column-start: 6;
}

上面代码的效果演示图

如果省略结束栅格线,那么结束栅格线使用序列中的下一条栅格线。

此外,还可以使用另一种方式:把结束值改为 span 1,或者只使用 span。

.three {
  grid-row-start: 4;
  grid-row-end: span 1;
  grid-column-start: 6;
  grid-column-end: span;
}

如果 span 后面有数字,意思是“跨指定数目的栅格轨道”。如果 span 后面没有数字,默认为 1。

对结束线来说,auto 通常指跨一个栅格单元后的栅格线。

grid-row 和 grid-column 属性

grid-row 属性是 grid-row-start 和 grid-row-end 的合并简写形式,grid-column 属性是 grid-column-start 和 grid-column-end 属性的合并简写形式。

.one {
  grid-row: R 3 / 7;
  grid-column: col-B / span 2;
}

在以斜线分隔的两部分中,前一部分定义的是开始栅格线,后一部分定义的是结束栅格线。

如果值中没有斜线,那么定义的是开始栅格线,结束栅格线取决于开始栅格线的值。如果开始栅格线是用名称引用的,那么结束栅格线也使用那个名称引用。因此,下面两个声明是等效的:

grid-column: col-B;
grid-column: col-B / col-B;

如果只提供一个数字,那么第二个数字(即结束线的编号)被设为 auto。因此,下面两个声明式等效的:

grid-row: 2;
grid-row: 2 / auto;

grid-area 属性

通过行线和列线附加元素是不错,但是我们可以只使用一个属性引用栅格区域,那就是 grid-area 属性。

这个属性适用于栅格元素和绝对定位的元素(前提是容纳块为栅格容器)。

grid-area 较为简单的用法:把元素指定给定义好的栅格区域。

#grid {
  display: grid;
  grid-template-areas: "header   header  header  header"
                       "leftside content contnet rightside"
                       "leftside footer  footer  footer";
}

#masthead {
  grid-area: header;
}

#sidebar {
  grid-area: leftside;
}

#main {
  grid-area: contnet;
}

#navbar {
  grid-area: rightside;
}

#footer {
  grid-area: footer;
}
<div id="grid">
  <div id="masthead">...</div>
  <div id="main">...</div>
  <div id="navbar">...</div>
  <div id="sidebar">...</div>
  <div id="footer">...</div>
</div>

上面代码的效果演示图

就是这么简单:先设置一些具名栅格区域,定义布局,然后通过 grid-area 把栅格元素放入指定区域。

此外,还可以使用 grid-area 引用栅格线。

.box03 {
  grid-area: 1 / 1 / 2 / 2;
}

栅格线值的顺序:row-start、column-start、row-end、column-end,这些值是按逆时针排列的。

justify-self 和 align-self 属性

justify-self 和 align-self 两个属性适用于栅格元素,分别在横向和纵向上对齐单个元素。

可选值(部分)演示图

分层和排序

如果栅格元素之间发生了重叠的情况,可以使用 z-index 属性指定栅格元素的重叠顺序。

小结

栅格布局复杂而强大,需要花些时间才能掌握。

没有吃透也不要灰心,在艰辛而曲折的学习过程中,耐心和毅力总会有回报。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant