Laurent
Laurent

Reputation: 1563

Row span without affecting other rows

I'm trying to figure out how to display a div over multiple rows without affecting the height of others div elements using the same rows.

Here is an example:

#wrapper {
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  grid-template-rows: repeat(12, minmax(0, 1fr));
  grid-template-rows: auto;
}

#navigation {
  grid-column-start: 1;
  grid-column-end: 13;
  background-color: #CCC;
  grid-row: 1;
}

#hero {
  grid-column-start: 1;
  grid-column-end: 13;
  background-color: #BBB;
  grid-row: 2;
}

#left1 {
  grid-column-start: 1;
  grid-column-end: 4;
  grid-row: 3;
  background-color: #AAA;
}

#left2 {
  grid-column-start: 1;
  grid-column-end: 4;
  grid-row: 4;
  background-color: #DDD;
}

#right {
  grid-column-start: 4;
  grid-column-end: 13;
  grid-row: 3/5;
  background-color: #EEE;
}
<div id="wrapper">
  <div id="navigation">NAVIGATION</div>
  <div id="hero">HERO IMAGE</div>
  <div id="left1">Left1</div>
  <div id="left2">Left2</div>
  <div id="right">Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right
    Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right
    Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right
    Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right
    Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right
    Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right
    Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right </div>
</div>

The div called #right is always going to be much longer than #left1 and #left2. If I put them aside, #right will increase the height of #left1 and #left2 and I would like to avoid that.

I could fix the problem by defining row heights in the grid definition but I'm never 100% sure how big #left1 and #left2 will be.

Example:

grid-template-rows: 50px 400px 300px 300px auto;

That works when dimensions are not exceeding those values but what I need is a "fit to content" approach for all div elements without creating dependencies between them.

Is that achievable with grid?

Thanks

Upvotes: 1

Views: 962

Answers (1)

Michael Benjamin
Michael Benjamin

Reputation: 371213

Your rows are set to auto height.

#wrapper {
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  grid-template-rows: repeat(12, minmax(0, 1fr)); <--  ignored; overruled
  grid-template-rows: auto; <-- winning rule
}

This means that the height of the first row (explicit grid) will be determined by content height.

The height of the remaining rows (implicit grid) will also be determined by the content height, because the default setting for grid-auto-rows is also auto.

It also means that a CSS Grid rule goes into effect: Free space among grid tracks with auto sizing is divided equally among them.

§ 11.8. Stretch auto Tracks

This step expands tracks that have an auto max track sizing function by dividing any remaining positive, definite free space equally amongst them. If the free space is indefinite, but the grid container has a definite min-width/height, use that size to calculate the free space for this step instead.

So when #left1 and #left2 share the same tracks with #right1, the free space (created in the left areas because the right area is taller) is distributed equally among the left areas.

But if the #right1 area is made to span into an empty, undefined row (let's say, from grid-row: 3/5 to grid-row: 3/6) it's no longer bound to the #left1 and #left2 tracks, and the auto stretch algorithm no longer applies.

#wrapper {
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  grid-template-rows: repeat(12, minmax(0, 1fr));
  grid-template-rows: auto;
}

#navigation {
  grid-column-start: 1;
  grid-column-end: 13;
  background-color: #CCC;
  grid-row: 1;
}

#hero {
  grid-column-start: 1;
  grid-column-end: 13;
  background-color: #BBB;
  grid-row: 2;
}

#left1 {
  grid-column-start: 1;
  grid-column-end: 4;
  grid-row: 3;
  background-color: #AAA;
}

#left2 {
  grid-column-start: 1;
  grid-column-end: 4;
  grid-row: 4;
  background-color: #DDD;
}

#right {
  grid-column-start: 4;
  grid-column-end: 13;
  /* grid-row: 3/5; */
  grid-row: 3/6;   /* new */
  background-color: #EEE;
}
<div id="wrapper">
  <div id="navigation">NAVIGATION</div>
  <div id="hero">HERO IMAGE</div>
  <div id="left1">Left1</div>
  <div id="left2">Left2</div>
  <div id="right">Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right
    Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right
    Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right
    Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right
    Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right
    Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right
    Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right </div>
</div>


In all honesty, I'm about 60% sure this answer is fully correct and 80% sure it's partially correct. Mostly because spanning #right to a new row still creates a new (third) area in the left column which is also, presumably, sized to auto, like its two siblings above.

So why doesn't "#left3" behave like #left1 and #left2? (i.e., equal distribution of free space)

I'm thinking it's because "#left3" is empty (HTML) and undefined (CSS).

In any case, the spec language isn't entirely clear to me and the Track Sizing Algorithm is much more complex than the Stretch auto Tracks section cited above. So there may be other factors in play.

Upvotes: 1

Related Questions