Skip to content Skip to sidebar Skip to footer

How To Prevent Grid-row Span From Changing Column Placement?

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 tw

Solution 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;
}
<divclass="grid-container"><divclass="b"><h1>A</h1></div><divclass="b"><h1>B</h1></div><divclass="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

part 1

part 2

Solution 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;
}
<divclass="grid-container"><div><h1>A</h1></div><div><h1>B</h1></div><divclass="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;
}
<divclass="grid-container"><div><h1>A</h1></div><div><h1>B</h1></div><divclass="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;
}
<divclass="grid-container"><div><h1>A</h1></div><div><h1>B</h1></div><divclass="a"><h1>C</h1></div></div><divclass="grid-container"><div><h1>A</h1></div><divclass="a"><h1>B</h1></div><div><h1>C</h1></div></div><divclass="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><divclass="a"><h1>F</h1></div><div><h1>G</h1></div><div><h1>H</h1></div></div><hr/><divclass="grid-container"><div><h1>A</h1></div><div><h1>B</h1></div><divclass="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>

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

Post a Comment for "How To Prevent Grid-row Span From Changing Column Placement?"