为什么具有网格区域名称但未在grid-template-area中定义的网格项目会创建附加列? [英] Why does a grid item with a grid-area name, but not defined in grid-template-areas, create an additional column?

查看:55
本文介绍了为什么具有网格区域名称但未在grid-template-area中定义的网格项目会创建附加列?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

相反,我从grid-template-areas开始,并通过grid-area属性为网格项分配了区域名称.

在那之后,我对如果从grid-template-areas中删除 grid-item 会发生什么感兴趣.结果有点奇怪.

已删除的网格项位于右侧,并由附加列分隔.

问题:

为什么会这样?这是预期的行为还是我的代码中遗漏了某些东西?如何删除此列?

 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.内容的高度(更多详细信息).因此,任何没有内容的行都只会折叠并且不可见.

宽度不存在此问题,因为在这种情况下,您使用的是块级容器(由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>Header</header>
<main>Main</main>
<footer>Footer</footer> 

注意:如果您使用过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>Header</header>
<main>Main</main>
<footer>Footer</footer> 


2. grid-area属性.

grid-area属性指定名称会创建区域的每一侧都命名为线.

例如,grid-area: header依次解析如下:

  • grid-row-start: header
  • grid-column-start: header
  • grid-row-end: header
  • grid-column-end: header

类似于marginborderpaddinggrid-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>Header</header>
<main>Main</main>
<footer>Footer</footer> 


3. grid-template-areas属性.

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

对于 ,将创建​​一个新行.

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

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

 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;
}
 

 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设置它们的大小,则 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>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去哪里了?

正如我们已经看到的,它被发送到隐式网格中,分为两列和两行.

网格区域由网格自动放置算法,看起来像这样:

  1. 由于未明确定义grid-area: main(请参见上文第3节),因此它属于隐式网格.

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

I've created a simple CSS Grid, I decided to not specify grid-template, grid-template-columns, grid-template-rows properties.

Instead, I started with grid-template-areas, and assigned area names to the grid-items via grid-area property.

After that, I was interested in what would happen if I remove grid-item from grid-template-areas. The result was kind of strange.

The removed grid-item was placed on the right and separated by additional column.

The problem:

Why did this happen? Is this expected behaviour or did I miss something in my code? How can I remove this column?

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>

解决方案

There are four parts to this answer. The first three help explain the fourth, which covers the reason for the extra column. If you're only interested in the answer, skip to the end.

Contents:

  1. More than meets the eye: There's also an extra row!
  2. The grid-area property.
  3. The grid-template-areas property.
  4. The placement of unreferenced grid areas.


1. More than meets the eye: There's also an extra row!

You've only partially defined the problem. Yes, there's an extra column. But there's also an extra row.

Because you haven't defined a height on the grid container, the height defaults to auto – the height of the content (more details). So any rows with no content simply collapse and are invisible.

This issue doesn't exist with width because, in this case, you're using a block-level container (created by display: grid), which is designed to consume the full width of its parent, by default (more details).

So that's why you're not seeing the extra row. If you give the container some height, the row will appear.

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>Header</header>
<main>Main</main>
<footer>Footer</footer>

Note: If you had used display: inline-grid, both the extra row and the extra column would have been invisible.

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>Header</header>
<main>Main</main>
<footer>Footer</footer>


2. The grid-area property.

Giving a name to the grid-area property creates a named line for each side of the area.

For example, grid-area: header resolves, in order, like this:

  • grid-row-start: header
  • grid-column-start: header
  • grid-row-end: header
  • grid-column-end: header

Like margin, border and padding, the grid-area property is a shorthand property. Unlike those properties, grid-area has a counterclockwise resolution order (in LTR languages), as illustrated above.

Because named grid areas occupy space, they need rows and columns in which to exist. Hence, named grid areas always impact the layout, even when they're not referenced in grid-template-areas.

So all that is necessary to "fix" your layout is to 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>Header</header>
<main>Main</main>
<footer>Footer</footer>


3. The grid-template-areas property.

Rows and columns (a/k/a tracks) that are created using grid-template-rows, grid-template-columns or grid-template-areas belong to the explicit grid. Any tracks not defined by those properties belong to the implicit grid (source).

For every string listed in grid-template-areas, a new row is created.

For every name or sequence of dots (...) in the string, a new column is created (but this doesn't apply in this case because each string has only one name).

Your code creates an explicit grid with two rows and one column:

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

As you can see in the image, header and footer have their own rows and exist in column one, exactly as defined in grid-template-areas.

The additional two rows and two columns are part of the implicit grid.

We can verify this by sizing them.

grid-template-columns works only on explicit columns.

grid-auto-columns works mostly on implicit columns (see note below).

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>Header</header>
<main>Main</main>
<footer>Footer</footer>

Note: If grid items are placed using grid-template-areas (creating explicit tracks), but they are not sized using grid-template-columns / grid-template-rows, then 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;
}

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. The placement of unreferenced grid areas.

Note: To be perfectly honest, I'm about 75% sure this section is completely correct. The spec language was not 100% clear to me. I welcome feedback, corrections, and more accurate answers.

In your code you have a third grid area which is not referenced in grid-template-areas.

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

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

Where does grid-area: main go?

As we've already seen, it gets sent into the implicit grid, two columns and two rows in.

The grid area is handled by the grid auto-placement algorithm, which appears to say this:

  1. Because grid-area: main isn't explicitly defined (see section 3 above), it belongs in the implicit grid.

  2. Because grid column line 2 and grid row line 3 (the boundaries of the explicit grid) are named grid lines, new lines must be created in the implicit grid to accommodate the four named lines of grid-area: main. This can only happen with an empty row and empty column in between, separating the explicit grid from the auto-placed implicit grid area.

这篇关于为什么具有网格区域名称但未在grid-template-area中定义的网格项目会创建附加列?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆