Reputation: 1563
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
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.
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 definitemin-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