自动边距可以像在 Flexbox 中那样在 CSS 网格中工作吗?

Can auto margins work in CSS Grid like they do in Flexbox?

据我了解,flexbox 可以做的任何事情,css-grid 也应该可以做(通常更冗长)。

但是我不知道如何用 margin: auto

来模仿一个项目推开其他项目的 flexbox

ul {
  list-style-type: none;
  padding: 0;
  display: flex;
  flex-direction: column;
  outline: 1px solid red;
  height: 200px;
  background-color: lime;
}

li {
  background-color: cornsilk;
}

li:last-of-type {
  margin-top: auto;
}
<ul>
  <li>1</li>
  <li>2</li>
  <li>3</li>
  <li>4</li>
</ul>

看看所有单元格的大小如何根据其内容调整,最后一个 li 将其他单元格推开以显示在最后?

如何在不修改 html 以添加元素的情况下使用 css-grid 执行此操作?

ul {
  list-style-type: none;
  padding: 0;
  display: grid;
  outline: 1px solid red;
  height: 200px;
  background-color: lime;
}

li {
  background-color: cornsilk;
}

li:last-of-type {
  margin-top: auto;
}
<ul>
  <li>1</li>
  <li>2</li>
  <li>3</li>
  <li>4</li>
</ul>

这很接近,但是所有行的大小都没有达到 min-content - 我不知道它们的大小是多少,但不是 min-content。我能得到的最接近的是添加

grid-template-rows: repeat(3, min-content);

这有效,但前提是您提前知道 lis 的数量,这对于 flexbox 版本来说不是必需的。

需要利用grid-template-rows来声明每行所占的区域 其中

  • minmax(1px, auto) 定义最小高度为1px,最大高度可以随着内容的增加动态扩展为前3里
  • 1fr 是 last li.
  • 剩余 space 的一小部分

ul {
  list-style-type: none;
  padding: 0;
  display: grid;
  outline: 1px solid red;
  height: 200px;
  background-color: lime;
  grid-template-rows: minmax(1px, auto) minmax(1px, auto) minmax(1px, auto) 1fr;
}

li {
  background-color: cornsilk;
}

li:last-of-type {
  margin-top: auto;
}
<ul>
  <li>1</li>
  <li>2</li>
  <li>3</li>
  <li>4</li>
</ul>

进一步说明,CSS 网格并不能真正取代 flexbox 的需要。 https://css-tricks.com/css-grid-replace-flexbox/

一般来说,对于 flexbox 中的对齐,有两个级别需要管理:

  1. 弹性容器,
  2. 弹性项目。

在CSS 网格中,需要管理三个级别:

  1. 网格容器,
  2. 行/列 ("tracks"),以及
  3. 网格项(存在于轨道内)。

当您在弹性项目上设置 auto 边距时,它会占用容器 中的 space。这足以 space 一个项目远离它的兄弟姐妹。大功告成。

当您在网格项上设置 auto 边距时,它会占用轨道 (而非容器)中的 space。因此您的曲目不受 auto 边距的影响。

您可以在您的网格示例中看到这一点。 margin-top: auto 的项目固定在 轨道 的底部。而在 Flex 示例中,它固定在容器的底部。

Grid 没有同类方法来模拟这种 flexbox 行为,因为如上所述,在一种情况下您有容器-项目关系,而在另一种情况下您有容器-轨道-项目关系。

换句话说,由于您要处理的所有项目都在 flexbox 的同一行 中,因此它们之间的间距很容易。由于您处理的项目 存在于 Grid 的不同行中,因此更加复杂。

您需要将 auto 边距应用到网格行,而不是项目,以使其表现得像 flexbox。或者,您需要定位并扩展特定的 grid-row-gap。 None 这些方法存在。该规范未规定网格轨道上的 auto 边距或 multiple values on grid gaps in the same axis.

CSS Grid 不是用来代替 flexbox 的。它甚至不是增强版。因此,期望找到 flex 比 Grid 更有用的情况。这个post就是一个很好的例子。

以下是 flexbox 可能具有优势的另外两个示例:

有一种方法可以获取您的请求,虽然有点老套,但很有效。

在所有列表元素和最后一个元素之间创建任意数量的未使用行。这里有一个片段,只要列表中的元素少于 99 个就可以使用:

ul {
  list-style-type: none;
  padding: 0;
  display: grid;
  outline: 1px solid red;
  height: 150px;
  background-color: lime;
  grid-template-rows: repeat(99, max-content) 1fr [last];
}

li {
  background-color: cornsilk;
}

li:last-of-type {
  grid-row: last;
}
<ul>
  <li>1</li>
  <li>2</li>
  <li>3</li>
  <li>4</li>
</ul>
<ul>
  <li>1</li>
  <li>2</li>
  <li>3</li>
</ul>

网格非常适合在二维中排列 html 块。 我会在这些 html 块中使用 flexbox 来安排内容。 Grid 就像 html 表格,而 flexbox 就像内联块。