如何防止网格行跨度改变列位置?

How to prevent grid-row span from changing column placement?

我有一个 3 X 3 CSS Grid

我有一行,其中有三个项目 ABC

我希望商品 Crowspan 为 2。

为此,我使用 grid-row: 1 / span 2;。它占用两行,但它被放置在第一列而不是简单地位于第三列。我不知道为什么会这样。

我希望项目 C 留在它在 HTML 中的位置。

解决此问题的一个方法是显式设置 grid-column: 3 / span 1,我不想这样做。我希望项目按它们在 HTML 中的方式放置。

有什么办法可以抑制这种行为吗?

.grid-container {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: repeat(3, 1fr);
}

h1 {
  border: 2px solid;
  padding: 0;
  margin: 0;
  font-size: 20px;
}

.a {
  grid-row: 1 / span 2;
  background: orange;
}
<div class="grid-container">
  <div>
    <h1>A</h1>
  </div>
  <div>
    <h1>B</h1>
  </div>
  <div class="a">
    <h1>C</h1>
  </div>
</div>

如果只有一个库存到行号,它将排在第一位并在流程中保持领先。为避免这种情况,其他网格项目也需要设置为默认行。

.grid-container {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: repeat(3, 1fr);
}

div {
  grid-row: 1;/* here is the basic fix but will set each item on first row */
}

h1 {
  border: 2px solid;
  padding: 0;
  margin: 0;
  font-size: 20px;
}

.a {
  grid-row: 1 / span 2;
  background: orange;
}
<div class="grid-container">
  <div>
    <h1>A</h1>
  </div>
  <div>
    <h1>B</h1>
  </div>
  <div class="a">
    <h1>C</h1>
  </div>
</div>

否则你还需要告诉 grid-column 它应该站在哪个

.a {
  grid-row: 1 / span 2;
  grid-column:3;
  background: orange;
}

.grid-container {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: repeat(3, 1fr);
}

h1 {
  border: 2px solid;
  padding: 0;
  margin: 0;
  font-size: 20px;
}

.a {
  grid-row: 1 / span 2;
  grid-column:3;
  background: orange;
}
<div class="grid-container">
  <div>
    <h1>A</h1>
  </div>
  <div>
    <h1>B</h1>
  </div>
  <div class="a">
    <h1>C</h1>
  </div>
</div>

或者让自动放置完成它的工作,同时只设置要跨越的行数,在这里,在我看来,最灵活的方式,最少 css rules/selector 设置,太多的网格会杀死网格 :),简单点:

.a {
  grid-row:  span 2;
  background: orange;
}

有几个例子的片段让 .aclass 完成它的工作而不设置列或行号的位置,它只会跨越它在流程中的位置

.grid-container {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: repeat(3, 1fr);
}

h1 {
  border: 2px solid;
  padding: 0;
  margin: 0;
  font-size: 20px;
}

.a {
  grid-row: span 2;
  background: orange;
}
<div class="grid-container">
  <div>
    <h1>A</h1>
  </div>
  <div>
    <h1>B</h1>
  </div>
  <div class="a">
    <h1>C</h1>
  </div>
</div>

<div class="grid-container">
  <div>
    <h1>A</h1>
  </div>
  <div class="a">
    <h1>B</h1>
  </div>
  <div>
    <h1>C</h1>
  </div>
</div>


<div class="grid-container">
  <div>
    <h1>A</h1>
  </div>
  <div>
    <h1>B</h1>
  </div>
  <div>
    <h1>C</h1>
  </div>
  <div>
    <h1>D</h1>
  </div>
  <div>
    <h1>E</h1>
  </div>
  <div class="a">
    <h1>F</h1>
  </div>
  <div>
    <h1>G</h1>
  </div>
  <div>
    <h1>H</h1>
  </div>
</div>
<hr/>
<div class="grid-container">
  <div>
    <h1>A</h1>
  </div>
  <div>
    <h1>B</h1>
  </div>
  <div class="a">
    <h1>C</h1>
  </div>
  <div>
    <h1>D</h1>
  </div>
  <div>
    <h1>E</h1>
  </div>
  <div>
    <h1>F</h1>
  </div>
  <div>
    <h1>G</h1>
  </div>
  <div>
    <h1>H</h1>
  </div>
</div>

很明显,规范中的某些内容会导致此行为。我还不确定它是什么。 (更新:有关解释,请参阅 。)

但是,这里有一个有效且简单的解决方案:

而不是:

.a {
  grid-row: 1 / span 2;
}

使用:

.a {
  grid-row-end: span 2;
}

来自规范:

9.3. Line-based Placement: the grid-row-start, grid-column-start, grid-row-end, and grid-column-end properties

The grid-row-start, grid-column-start, grid-row-end, and grid-column-end properties determine a grid item’s size and location within the grid by contributing a line, a span, or nothing (automatic) to its grid placement, thereby specifying the inline-start, block-start, inline-end, and block-end edges of its grid area.

...

For example, grid-column-end: span 2 indicates the second grid line in the endward direction from the grid-column-start line.


此外,请考虑这条让您完全控制并使一切正常运行的单一规则:

.a {
  grid-area: 1 / 3 /  3 / 4;
}

jsFiddle

grid-areashorthand属性按以下顺序解析值:

  • grid-row-start
  • grid-column-start
  • grid-row-end
  • grid-column-end

注意逆时针方向,与marginpadding相反。

另一种解决方法(这指出了 为什么 为其他项目声明一行的原因):

.grid-container {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: repeat(3, 1fr);
}

h1 {
  border: 2px solid;
  padding: 0;
  margin: 0;
  font-size: 20px;
}

.a {
  grid-row: 1 / span 2;
  background: orange;
}

.b {
  grid-row: 1;
}
<div class="grid-container">
  <div class="b">
    <h1>A</h1>
  </div>
  <div class="b">
    <h1>B</h1>
  </div>
  <div class="a">
    <h1>C</h1>
  </div>
</div>

这种行为的原因是限制性更强的元素首先被定位。这样,网格算法求解的可能性就更大了。

即有需求的元素先定位,没有需求的元素最后。

part of the spec

中的第 2 步(针对 一项 项)和第 4 步(针对其余项)