How to prevent grid row range from changing when column layout changes?

I have a 3 X 3 CSS Grid .

I have a string where I have three elements A

, B

and C

.

I want the element to C

have rowspan

of 2.

For this I use grid-row: 1 / span 2;

. It spans two lines, but fits in the first column, not just in the third column. I don't know why this is happening.

I want the C element to stay where it is in the HTML.

One way to fix this is to explicitly install grid-column: 3 / span 1

, which I don't want to do. I want the elements to be laid out the way they are in HTML.

Is there a 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>
      

Run codeHide result


+3


source to share


3 answers


Another way to solve it (This indicates the reason why it specifies a string for other elements):

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

Run codeHide result


And the reason for this behavior is that more restrictive elements are positioned first. Thus, the possibilities of the grid algorithm to achieve a solution are greater.



That is, the item that has a requirement will be placed first, items that do not have the last requirement.

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

part 1

part 2

+5


source


If only one gets the stock to the line number, he will be the first and stand there in the stream. To avoid this, other grid items must also be set to the defaut line.



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

Run codeHide result


Otherwise, you also need to say which one grid-column

it should stand in.

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

Run codeHide result


or let the auto-placement do its job by only setting the number of lines, which here is the most flexible way in my opinion with the minimum amount of css rules / selectors to set, too much grid kills the grid :), keep it simple:

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

      

with a few examples to allow .aclass to do its job without setting the column or row number to where to stand, it will just cover where it is put in the stream



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

Run codeHide result


+1


source


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

However, here's a fair and simple solution:

Instead:

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

      

Using:

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

      

From the specification:

9.3. Linear accommodation: grid-row-start

, grid-column-start

, grid-row-end

and grid-column-end

Properties

grid-row-start

, grid-column-start

, grid-row-end

And properties grid-column-end

determine the size and location of the grid within the grid elements by making the line of flight or nothing (automatic) to its placement grid, thus indicating embedded start, block start and end of the embedded block end edge of its grid area.

...

For example, grid-column-end: span 2

indicates the second grid line in the final direction from the line grid-column-start

.


Also, consider this one rule that gives you complete control and makes it all work:

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

      

jsFiddle

grid-area

The shorthand property parses values ​​in the following order:

  • grid-row-start

  • grid-column-start

  • grid-row-end

  • grid-column-end

Note the counterclockwise direction, which is opposite to margin

and padding

.

+1


source







All Articles