我创建了一个简单的CSS网格,我决定不指定grid-template
,grid-template-columns
,grid-template-rows
的属性。
相反,我从开始grid-template-areas
,并通过属性将区域名称分配给了网格项grid-area
。
之后,我对如果从中删除grid-item会发生什么感兴趣grid-template-areas
。结果有点奇怪。
删除的网格项目位于右侧,并由其他列分隔。
问题:
为什么会这样呢?这是预期的行为还是我的代码中遗漏了某些东西?如何删除此列?
body {
display: grid;
grid-template-areas:
"header"
"footer";
}
header {
grid-area: header;
background: lightblue;
}
main {
grid-area: main;
background: darkorange;
}
footer {
grid-area: footer;
background: blue;
}
Header
Main
Michael_B.. 10
这个答案分为四个部分。前三个帮助说明了第四个,其中涵盖了添加额外列的原因。如果您只对答案感兴趣,请跳到最后。
内容:
不仅让人眼前一亮:还有额外的一排!
该grid-area
属性。
该grid-template-areas
属性。
未引用网格区域的位置。
您仅部分定义了问题。是的,还有一栏。但是,还有另外一排。
由于尚未在网格容器上定义高度,因此该高度默认为auto
–内容的高度(更多详细信息)。因此,没有内容的任何行都只会折叠并且不可见。
宽度不存在此问题,因为在这种情况下,您使用的是块级容器(由创建display: grid
),默认情况下,该容器旨在消耗其父级的全部宽度(更多详细信息)。
这就是为什么您看不到多余的行。如果您给容器增加一些高度,则会出现该行。
body {
display: grid;
grid-template-areas:
"header"
"footer";
height: 150px; /* new */
}
body {
display: grid;
grid-template-areas:
"header"
"footer";
height: 150px; /* new */
}
header {
grid-area: header;
background: aqua;
}
main {
grid-area: main;
background: darkorange;
}
footer {
grid-area: footer;
background: lightgreen;
}
Header
Main
注意:如果使用过display: inline-grid
,则多余的行和多余的列都将是不可见的。
body {
display: inline-grid;
grid-template-areas:
"header"
"footer";
}
body {
display: inline-grid; /* adjustment */
grid-template-areas:
"header"
"footer";
}
header {
grid-area: header;
background: aqua;
}
main {
grid-area: main;
background: darkorange;
}
footer {
grid-area: footer;
background: lightgreen;
}
Header
Main
grid-area
财产。给该grid-area
属性命名将为该区域的每一侧创建一个命名行。
例如,grid-area: header
按顺序解析,如下所示:
grid-row-start: header
grid-column-start: header
grid-row-end: header
grid-column-end: header
像和一样margin
,该属性是简写属性。与那些属性不同,如上所述,具有逆时针分辨率顺序(使用LTR语言)。border
padding
grid-area
grid-area
因为命名网格区域占据空间,所以它们需要在其中存在行和列。因此,即使未在中引用命名网格区域,也始终会影响布局grid-template-areas
。
因此,“固定”布局所需的所有操作都是remove grid-area: main
。
main {
/* grid-area: main; */
background: darkorange;
}
body {
display: grid;
grid-template-areas:
"header"
"footer";
}
header {
grid-area: header;
background: aqua;
}
main {
/* grid-area: main; */
background: darkorange;
}
footer {
grid-area: footer;
background: lightgreen;
}
Header
Main
grid-template-areas
财产。行和列(A / K / A磁道)正在使用创建的grid-template-rows
,grid-template-columns
或者grid-template-areas
属于明确的格。这些属性未定义的任何轨道都属于隐式网格(源)。
对于中列出的每个字符串grid-template-areas
,都会创建一个新行。
对于...
字符串中的每个名称或点序列(),都会创建一个新列(但这不适用于这种情况,因为每个字符串只有一个名称)。
您的代码创建一个具有两行一列的显式网格:
body {
display: grid;
grid-template-areas:
"header"
"footer";
}
正如你可以在图片中看到,header
并footer
有自己的行存在于一列,完全按照规定grid-template-areas
。
额外的两行两列是隐式网格的一部分。
我们可以通过调整大小来验证这一点。
grid-template-columns
仅适用于显式列。
grid-auto-columns
作品大多隐列(见下面的说明)。
body {
display: grid;
grid-template-areas: "header" "footer";
grid-template-columns: 1fr;
grid-auto-columns: 100px;
grid-template-rows: 100px 100px;
grid-auto-rows: 25px;
}
body {
display: grid;
grid-template-areas:
"header"
"footer";
grid-template-columns: 1fr;
grid-auto-columns: 100px;
grid-template-rows: 100px 100px;
grid-auto-rows: 25px;
}
header {
grid-area: header;
background: aqua;
}
main {
grid-area: main;
background: darkorange;
}
footer {
grid-area: footer;
background: lightgreen;
}
Header
Main
注意:如果使用grid-template-areas
(创建显式轨道)放置网格项目,但未使用grid-template-columns
/ 调整网格项目的大小grid-template-rows
,则grid-auto-columns
/ grid-auto-rows
应用于它们。(第二段)
body {
display: grid;
grid-template-areas:
"header"
"footer";
grid-auto-columns: 100px;
grid-auto-rows: 25px;
}
body {
display: grid;
grid-template-areas:
"header"
"footer";
grid-auto-columns: 100px;
grid-auto-rows: 25px;
}
header {
grid-area: header;
background: aqua;
}
main {
grid-area: main;
background: darkorange;
}
footer {
grid-area: footer;
background: lightgreen;
}
Header
Main
注意:老实说,我大约有75%的人确定此部分完全正确。规范语言对我来说不是100%清晰的。我欢迎您提供反馈,更正和更准确的答案。
在您的代码中,您有第三个网格区域,未在中引用grid-template-areas
。
body {
display: grid;
grid-template-areas:
"header"
"footer";
}
main {
grid-area: main;
background: darkorange;
}
哪里grid-area: main
去了?
正如我们已经看到的,它被发送到隐式网格(两列两行)中。
网格区域由网格自动放置算法处理,该算法看起来像这样:
由于grid-area: main
未明确定义(请参见上文第3节),因此它属于隐式网格。
由于网格列线2和网格行线3(显式网格的边界)被命名为网格线,因此必须在隐式网格中创建新线以容纳的四个命名线grid-area: main
。只有在空行和空列之间,将显式网格与自动放置的隐式网格区域分开时,才会发生这种情况。
Temani Afif.. 8
这是对Michael_B已经说过的内容的扩展,以突出显示如何创建隐式网格线。
让我们从一个简单的例子开始:
.container {
width:100px;
display: inline-grid;
grid-auto-rows: 40px;
border: 1px solid;
}
header {
grid-row-start: header;
background: blue;
}
H
我们有一个网格项,仅在其中设置grid-row-start
,最终结果是两行,其中有一个空行。因为我们没有定义任何显式网格,所以它们都在隐式网格中。
要了解发生了什么,请参考规范:
网格模板行,网格模板列和网格模板区域这三个属性共同定义了网格容器的显式网格。...如果这些属性没有定义任何明确的轨迹,则明确的网格在每个轴上仍然包含一条网格线。参考
因此,即使我们什么也没定义,我们仍然有一个包含两行的显式网格。这非常重要,因为如果没有这些行,我们将没有空行。
现在说明部分grid-row-start:header
:
第一次尝试将网格区域的边缘与命名网格区域匹配:如果有一条名为“ -start(对于grid- -start)/ -end”(对于 grid-- end)的命名行,则贡献第一个这样的行到网格项目的位置。
否则,将其视为
1
已与一起指定了整数。
显然,我们将陷入否则,将有grid-row-start:header 1
:
&& ? 将第N条网格线贡献给网格项目的位置...
如果将名称指定为
,则仅计算具有该名称的行。如果没有足够多的具有该名称的线,则假定所有隐式网格线都具有该名称,以查找该位置。
在我们的情况下,该名称的行数不够(根本没有任何行),因此我们应至少添加一行具有该名称的行,然后尝试放置元素,并且由于整数为正数,因此项目将放置在该行下方:
网格有一条默认行(红色),使用会在其下header
方生成一个新的隐式行(由于1
自动添加了默认值),并且该元素将放置在该行下方,从而创建了额外的一行。
如果我们使用-1
的话,最后只会有一行:
.container {
width:100px;
display: inline-grid;
grid-auto-rows: 40px;
border: 1px solid;
}
header {
grid-row-start: header -1;
background: blue;
}
H
在这种情况下,隐式线在显式一线上方生成,而我们的元素位于两行之间。
如果负整数给出,它代替计数反向,从起始显式网格的端部边缘。
同时使用-1
和1
将给我们以下结果:
.container {
width:100px;
display: inline-grid;
grid-auto-rows: 40px;
border: 1px solid;
}
header {
grid-row-start: header -1;
background: blue;
}
footer {
grid-row-start: header 1;
background: red;
}
H
这是另一个包含多个项目的示例,用于说明假定所有隐式网格线都具有该名称。
.container {
width:100px;
display: inline-grid;
grid-auto-rows: 40px;
border: 1px solid;
}
header {
grid-row-start: header 1;
background: blue;
}
main {
grid-row-start: main 1;
background: red;
}
footer {
grid-row-start: footer -1;
background: green;
}
extra {
grid-row-start: extra 5;
background: orange;
}
H
M
E
在此示例中,我们总共需要6条隐式行,因为所有使用的整数都在该范围内[-1,5]
(不包括0
无效值),并且,为了放置每个元素,所有这些行将具有为每个元素定义的名称。这就是为什么具有相同编号的两个元素将在同一行(如main
和header
),因为即使名称不同,参考线也将相同。
现在,让我们添加grid-row-end
到前面的示例中:
.container {
width:100px;
display: inline-grid;
grid-auto-rows: 40px;
border: 1px solid;
}
header {
grid-row-start: header;
grid-row-end: header;
background: blue;
}
H
什么都不会发生,并且会得到完全相同的结果,因为:
如果起点线等于终点线,请移除终点线。参考
让我们使用其他名称:
.container {
width:100px;
display: inline-grid;
grid-auto-rows: 40px;
border: 1px solid;
}
header {
grid-row-start: header;
grid-row-end: foo;
background: blue;
}
H
结果仍然相同,因为两者仍然相等(是的,它们相等!)。两个值都等于
,因此两个都只需要一条隐含线。然后,浏览器将创建一条具有两个不同名称的隐式行,从而使我们的两个值相等。
让我们更改一个的值:
.container {
width:100px;
display: inline-grid;
grid-auto-rows: 40px;
border: 1px solid;
}
header {
grid-row-start: header 1;
grid-row-end: foo 2;
background: blue;
}
H
再次得到相同的结果,但使用“不同”的代码。在这种情况下,我们将有2条隐式线,并且我们的元素将放置在它们之间。
基本上,涉及隐式网格时,该名称不相关,因为它们都将共享同一行。仅当我们在显式网格内定义它们时才有意义:
.container {
width:100px;
display: inline-grid;
grid-auto-rows: 40px;
border: 1px solid;
}
header {
grid-row-start: hello 1;
grid-row-end: john 3;
background: blue;
}
main {
grid-row-start: main 1;
grid-row-end: hi 2;
background: red;
}
footer {
grid-row-start: footer 2;
grid-row-end: custom 5;
background: green;
}
extra {
grid-row-start: extra 3;
grid-row-end: fsdfsdfsdfsd 5;
background: orange;
}
H
M
E
在上面的示例中,您可以使用任意随机字符串更新名称,并且始终会得到相同的结果。它仅取决于整数:
考虑到以上所有,从逻辑上讲,它们的行为相同grid-column-*
。
现在,我们拥有了解初始示例所发生的一切所需的一切。
首先,我们有如下所示的显式网格:
body {
display: grid;
grid-template-areas:
"header"
"footer";
/* No relevant but to better illustrate*/
grid-auto-rows:50px;
grid-auto-columns:50px;
}
header {
grid-area: header;
background: lightblue;
}
/*main {
grid-area: main;
background: darkorange;
}*/
footer {
grid-area: footer;
background: blue;
}
Header
grid-template-areas属性从模板中的命名网格区域创建隐式命名线。对于每个命名网格区域foo,将创建四行隐式命名行:两
foo-start
行named ,命名命名网格区域的行开始行和列起始行,两foo-end
行named ,命名命名网格区域的行末行和列末行网格区域。参考
现在,如果我们添加第三个元素,grid-area:main;
则意味着
grid-row-start:main 1;
grid-row-end:main 1;
grid-column-start:main 1;
grid-column-end:main 1;
我们删除,*-end
因为它们等于*-start
grid-row-start:main 1
grid-column-start:main 1
根据前面的解释,我们将需要一条额外的隐式线,main
并将我们的元素放置在水平线的下方和垂直线的右侧:
body {
display: grid;
grid-template-areas:
"header"
"footer";
/* No relevant but to better illustrate*/
grid-auto-rows:50px;
grid-auto-columns:50px;
}
header {
grid-area: header;
background: lightblue;
}
main {
grid-area: main;
background: darkorange;
}
footer {
grid-area: footer;
background: blue;
}
Header
Main
如果我们删除了grid-auto-*
,行会对其内容的高度,使得彼此的行footer-end
和main
空。该列将拆分网格元素的宽度,而网格元素是具有完整宽度的块元素。这就是为什么您只看到一个额外的列而不看到额外的行的原因:
body {
display: grid;
grid-template-areas:
"header"
"footer";
}
header {
grid-area: header;
background: lightblue;
}
main {
grid-area: main;
background: darkorange;
}
footer {
grid-area: footer;
background: blue;
}
Header
Main
另一个有趣的观察结果是,如果您使用添加更多元素grid-area:
,则它们都将位于彼此之上:
body {
display: grid;
grid-template-areas:
"header"
"footer";
}
header {
grid-area: header;
background: lightblue;
}
main {
grid-area: main;
background: darkorange;
}
footer {
grid-area: footer;
background: blue;
}
extra {
grid-area: extra;
background: red;
opacity:0.8;
}
more {
grid-area: more;
background: green;
opacity:0.3;
}
Header
Main
E
More
根据前面的解释,所有这些都将具有以下内容:
grid-row-start: 1;
grid-column-start: 1;
由于数字相同(名称与我们已经说明的名称无关),它们都将属于同一区域。
这个答案分为四个部分。前三个帮助说明了第四个,其中涵盖了添加额外列的原因。如果您只对答案感兴趣,请跳到最后。
内容:
不仅让人眼前一亮:还有额外的一排!
该grid-area
属性。
该grid-template-areas
属性。
未引用网格区域的位置。
您仅部分定义了问题。是的,还有一栏。但是,还有另外一排。
由于尚未在网格容器上定义高度,因此该高度默认为auto
–内容的高度(更多详细信息)。因此,没有内容的任何行都只会折叠并且不可见。
宽度不存在此问题,因为在这种情况下,您使用的是块级容器(由创建display: grid
),默认情况下,该容器旨在消耗其父级的全部宽度(更多详细信息)。
这就是为什么您看不到多余的行。如果您给容器增加一些高度,则会出现该行。
body {
display: grid;
grid-template-areas:
"header"
"footer";
height: 150px; /* new */
}
body {
display: grid;
grid-template-areas:
"header"
"footer";
height: 150px; /* new */
}
header {
grid-area: header;
background: aqua;
}
main {
grid-area: main;
background: darkorange;
}
footer {
grid-area: footer;
background: lightgreen;
}
Header
Main
这是对Michael_B已经说过的内容的扩展,以突出显示如何创建隐式网格线。
让我们从一个简单的例子开始:
.container {
width:100px;
display: inline-grid;
grid-auto-rows: 40px;
border: 1px solid;
}
header {
grid-row-start: header;
background: blue;
}
H