为什么在网格模板区域中没有网格区域名称会创建额外的轨迹?

2022-04-02 00:00:00 css css-grid

我已经创建了一个简单的CSS网格,我决定不指定grid-templategrid-template-columnsgrid-template-rows属性。

相反,我从grid-template-areas开始,并通过grid-area属性将区域名称分配给网格项目。

之后,我对从grid-template-areas中删除网格项会发生什么感兴趣。结果有点奇怪。

删除的网格项放在右侧,并由附加栏分隔。

问题:

为什么会发生这种情况?这是意料之中的行为,还是我在代码中遗漏了什么?如何删除此栏?

数据-lang="js"数据-隐藏="假"数据-控制台="真"数据-巴贝尔="假">
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>Header</header>
<main>Main</main>
<footer>Footer</footer>


解决方案

此答案分为四个部分。前三个帮助解释了第四个,它涵盖了增加专栏的原因。如果您只对答案感兴趣,请跳到结尾。

内容:

  1. 非同小可:还多了一排!
  2. grid-area属性。
  3. grid-template-areas属性。
  4. 未引用的网格区域的放置。

1.超乎想象:还多了一行!

您只定义了问题的一部分。是的,还有一个栏目。但也有额外的一行。

因为您没有在网格容器上定义高度,所以高度默认为auto&ndash;内容的高度(more details)。因此,任何没有内容的行都会折叠,并且不可见。

宽度不存在此问题,因为在本例中,您使用的是块级容器(由display: grid创建),默认情况下(more details)设计为使用其父对象的全宽度。

这就是为什么你看不到额外的一行。如果为容器指定一定的高度,则将显示该行。

body {
  display: grid;
  grid-template-areas:
    "header"
    "footer";
  height: 150px; /* new */ 
}

数据-lang="js"数据-隐藏="真"数据-控制台="真"数据-巴贝尔="假">
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>Header</header>
<main>Main</main>
<footer>Footer</footer>

注意:如果您使用display: inline-grid,额外的行和额外的列都将不可见。

body {
  display: inline-grid;
  grid-template-areas:
    "header"
    "footer";
}

数据-lang="js"数据-隐藏="真"数据-控制台="真"数据-巴贝尔="假">
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>Header</header>
<main>Main</main>
<footer>Footer</footer>


2.grid-area属性。

grid-area属性命名将为区域的每一侧创建一个named line。

例如,grid-area: header按如下顺序进行解析:

  • grid-row-start: header
  • grid-column-start: header
  • grid-row-end: header
  • grid-column-end: header
marginborderpadding一样,grid-area属性是速记属性。与这些属性不同,grid-area具有逆时针解析顺序(在Ltr语言中),如上所述。

因为命名网格区域占用空间,所以它们需要在其中存在行和列。因此,命名网格区域始终会影响布局,即使它们在grid-template-areas中未被引用。

因此,"修复"布局所需的全部操作就是删除grid-area: main

main {
  /* grid-area: main; */
  background: darkorange;
}

数据-lang="js"数据-隐藏="真"数据-控制台="真"数据-巴贝尔="假">
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>Header</header>
<main>Main</main>
<footer>Footer</footer>


3.grid-template-areas属性。

使用grid-template-rowsgrid-template-columnsgrid-template-areas创建的行和列(a/k/a轨道)属于显式网格。未由这些属性定义的任何曲目都属于隐式网格(source)。

grid-template-areas中列出的每个字符串创建一个新行。

对于字符串中的每个名称或点序列(...),都会创建一个新列(但这不适用于本例,因为每个字符串只有一个名称)。

您的代码创建了一个两行一列的显式网格:

body {
  display: grid;
  grid-template-areas: 
    "header"
    "footer";
}

如图所示,headerfooter有自己的行,并存在于第一列中,与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;
}

数据-lang="js"数据-隐藏="真"数据-控制台="真"数据-巴贝尔="假">
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>Header</header>
<main>Main</main>
<footer>Footer</footer>

注意:如果使用grid-template-areas(创建显式轨道)放置网格项目,但不使用grid-template-columns/grid-template-rows调整它们的大小,则grid-auto-columns / grid-auto-rows apply to them. (second paragraph)

body {
  display: grid;
  grid-template-areas:
      "header"
      "footer";
  grid-auto-columns: 100px;
  grid-auto-rows: 25px;
}

数据-lang="js"数据-隐藏="真"数据-控制台="真"数据-巴贝尔="假">
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>Header</header>
<main>Main</main>
<footer>Footer</footer>


4.未引用网格区域的放置。

注意:老实说,我大约75%肯定这一节是完全正确的。规范语言对我来说并不是100%清楚。我欢迎反馈、更正和更准确的答案。

在您的代码中,grid-template-areas中没有引用第三个网格区域。

body {
  display: grid;
  grid-template-areas: 
    "header"
    "footer";
}

main {
  grid-area: main;
  background: darkorange;
}

grid-area: main去哪里?

正如我们已经看到的,它被发送到隐式网格中,里面有两列和两行。

网格区域由grid auto-placement algorithm处理,它显示为:

  1. 因为grid-area: main没有显式定义(请参阅上面的第3节),所以它属于隐式网格。

    /li>
  2. 因为网格列线2和网格行线3(显式网格的边界)是命名网格线,所以必须在隐式网格中创建新线以容纳grid-area: main的四条命名线。只有在空行和空列之间分隔显式网格和自动放置的隐式网格区域时,才会发生这种情况。

相关文章