【问题标题】:Can auto margins work in CSS Grid like they do in Flexbox?自动边距可以在 CSS Grid 中像在 Flexbox 中那样工作吗?
【发布时间】:2018-06-07 13:02:00
【问题描述】:

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

但我不知道如何用margin: auto 推开其他项目来模仿弹性框

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 版本不是必需的。

【问题讨论】:

  • 如果您知道行数,这可以在不更改 HTML 的情况下完成。如果这是一个选项,请告诉我。
  • @Michael_B 谢谢,但我有十几种不同的方式来做我想做的事,这更多地是为了理解 CSS 网格的来龙去脉。那里有很多东西,我可以如此接近,如果没有办法做到这一点,我会感到惊讶根本。我期待有人过来说“只需使用这个你从未听说过的函数并传入负数和中提琴”或类似的话
  • 由于您正在处理所有在同一行与flexbox的项目,它们之间的间距很容易。由于您使用 Grid 处理存在于不同行的项目,因此复杂性更高。我不认为你的白衣骑士会出现在这种情况下。我的答案中有更多详细信息。

标签: html css flexbox css-grid


【解决方案1】:

Grid 非常适合在二维中排列 html 块。 我会在这些 html 块中使用 flexbox 来安排内容。 Grid 类似于 html 表格,flexbox 类似于 inline-block。

【讨论】:

    【解决方案2】:

    有一种方法可以获取您的请求,这可能被认为有点骇人听闻,但这是有效的。

    在所有列表元素和最后一个元素之间创建任意数量的未使用行。这里的 sn-p 将在列表少于 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>

    【讨论】:

    • 哦,这很有趣,实际上更接近我想要的,谢谢!就知道会有人来。这是“hackish”,但我认为并不是非常 hacky
    【解决方案3】:

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

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

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

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

    当您在弹性项目上设置auto 边距时,它会消耗容器中的空间。这足以将一个项目与其兄弟姐妹隔开。你已经完成了。

    当您在网格项目上设置auto 边距时,它会消耗轨道中的空间(而不是容器)。所以您的曲目不受auto 边距的影响。

    您可以在您的 Grid 示例中看到这一点。带有margin-top: auto 的项目被固定在track 的底部。而在 Flex 示例中,它被固定在容器的底部。

    对于 Grid 来说,没有苹果对苹果的方法来模拟这种 flexbox 行为,因为如上所述,在一种情况下,您有一个容器-项目关系,而在另一种情况下,您有一个容器-轨道-项目关系.

    换一种说法,因为你处理的是在flexbox中所有在同一行的项目,它们之间的间距很容易。由于您要处理在网格中的不同行中存在的项目,因此更加复杂。

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

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

    这里有另外两个 flexbox 可能具有优势的例子:

    【讨论】:

    • 我一直听说网格不能取代 flexbox,但如果我提出的建议确实不可能,这是我真正见过的第一个例子,即 flexbox 可以做到,而网格不能......
    • 我刚刚发布了另一个 :-)
    • 你确实做到了。我没有看到粘性页脚不是 possible 网格,只是更冗长(请参阅接受的答案)。包装是一个有趣的案例,你是对的。当然,flexbox 的包装内容仍然很糟糕(是否尝试过在包装内容时让行高适合内容?):P
    • 是的,但我没有说“不可能”使用 Grid。我说“flexbox可能有优势的地方” ;-)
    • 关于您的第二点——“是否曾尝试让行高适合内容包装?”。不,不使用 flexbox。效果不好。在这种情况下,Grid 胜出。我在这里介绍过:stackoverflow.com/q/44377343/3597276
    【解决方案4】:

    你需要使用grid-template-rows来声明每行占用的区域 在哪里

    • minmax(1px, auto) 定义最小高度为1px,最大高度可以随着前3 li的内容动态增加而扩展。
    • 1fr 是last li整个剩余空间的 1 分之一。

    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 Grid 并没有真正取代 flexbox。 https://css-tricks.com/css-grid-replace-flexbox/

    【讨论】:

    • 但这与我在问题末尾提出的解决方案存在相同的问题-您必须提前知道行数。这是 flexbox 不需要的东西,所以它不是很平等。
    • @GeorgeMauer 是的,这就是 grid 的工作原理,这就是为什么它不能真正取代 flexbox 的某些属性,但它们可以相互补充。参考:css-tricks.com/css-grid-replace-flexbox
    • 如果那是我记得看到我失望地离开的那篇文章——他们谈论了如何每个人都可以做对方做不到的事情,但只举例说明了网格可以做什么而 flexbox 不能。是的,“重新排序更容易”是很重要的一点,但在网格中以相同的方式重新排序是可能。同样,使用 CSS 网格您必须提前知道行数当然不是真的。我现在正在使用不硬编码的布局。 grid-auto-rows 是这里的关键。
    • @GeorgeMauer 在 ul 上使用 grid-auto-rows: min-content; 会给你一半的解决方案,然后你需要找到如何使最后一个元素到底部
    • @GeorgeMauer 但是你不能像上面的问题一样,在不知道提前发生的位置的情况下操纵某个行或列。要使其行为方式与 flexbox 完全相同,您需要一种解决方法。
    猜你喜欢
    • 2012-06-15
    • 2021-09-09
    • 2012-02-28
    • 1970-01-01
    • 2011-05-11
    • 2017-09-13
    • 1970-01-01
    • 2021-03-31
    • 2012-10-25
    相关资源
    最近更新 更多