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

ⅰ亾dé卋堺 提交于 2019-12-10 18:10:58

问题


I have a 3 X 3 CSS Grid.

I have a row in which I have three items A, B & C.

I want item C to have a rowspan of 2.

To do so, I am using grid-row: 1 / span 2;. It is taking two rows, but it's being placed in the first column instead of simply lying in the 3rd column. I don't know why this is happening.

I want item C to stay at the place where it is in the HTML.

One work around to this problem is to explicitly setting grid-column: 3 / span 1 which I don't want to do. I want items to be placed the way they are in HTML.

Is there any way to suppress this behavior?

.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>

回答1:


Another way of solving it (That points to the reason why is stating a row for the other items):

.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>

And the reason of this behaviour is that the more restrictive elements get positioned first. This way, the possibilities of the grid algorithm to achieve a solution are bigger.

That is, an element that has a requirement will be positioned first, elements that don't have a requirement last.

Steps 2 (for a item) and 4 (for the remaining items) in this part of the spec




回答2:


If only one gets stock to a row number it will come first and stick there ahead in the flow. To avoid this, other grid items needs to be set to a defaut row as well.

.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>

Else you need also to tell in which grid-column it should stand

.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>

or let auto placement do its job while only setting how many rows to span, wich is here, in my own opinion, the most flexible way with a minimum of css rules/selector to set, too much grid kills grid :) , make it simple :

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

snippet with a few example letting the .aclass do its job without setting the column nor the row number where to stand, it will just be spanning where it stans in the flow

.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>



回答3:


Clearly, there's something in the spec that causes this behavior. I'm not yet sure what it is. (Update: see @Vals' answer for an explanation.)

However, here's a valid and simple solution:

Instead of:

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

Use:

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

From the spec:

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.


Also, consider this single rule that gives you full control and makes it all work:

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

jsFiddle

The grid-area shorthand property parses values in this order:

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

Note the counter-clockwise direction, which is the opposite of margin and padding.



来源:https://stackoverflow.com/questions/43784655/how-to-prevent-grid-row-span-from-changing-column-placement

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!