-
Notifications
You must be signed in to change notification settings - Fork 759
Description
During the discussion at #9321 (comment) @fantasai raised a case where intrinsic auto repeats mixed with fixed track sizes could lead to overflow. I mentioned that in that case it wouldn't overflow, but this is because I forgot to divide by the span, which was needed to cause the overflow. So opening an issue to flesh out the use case and potential mitigations.
The use case that was raised was:
<style>
.masonry {
display: masonry;
background: gray;
grid-template-columns: repeat(auto-fill, 100px auto);
width: 500px;
height: 300px;
}
.masonry > div {
width: 300px;
height: 100px;
grid-column: span 2;
}
</style>
<body>
<div class="masonry">
<div style="background: lightskyblue;">
Number 1
</div>
<div style="background: lightcoral;">
Number 2
</div>
</div>
</body>
This renders as follows in Chromium:
This is because per the intrinsic auto repeat heuristic the following steps happen:
- We expand any intrinsic auto repeats once, resulting in
10px auto - We run an initial track sizing pass where we create a single spanning virtual item that gets the largest contribution from all items. Any spanning item's contribution is divided by its span. In this case, the virtual item gets a contribution size of
300/2or150px. - We run track sizing up through the intrinsic sizing pass, and take the growth limit of the virtual item as the size of
auto. In this case, that is150px - We then calculate the actual number of auto repeats for
100px autoor100px 150px. Since the available space is500px, we get 2 repeats, resulting in100px auto 100px auto - We then layout using the normal masonry algorithm, and the spanning items get placed in track 1 and track 3. Because they are 300px wide,
autoresolves to300 - 100or200px. This leads to a total of100 + 200 + 100 + 200sized columns, or600px, which ends up overflowing the500pxwide container.
The reason being that the heuristic to divide by the span size doesn't quite work in all cases when there are fixed track sizes mixed in.
Some potential options that I can think of:
Option 1:
Don't allow mixing of intrinsic track sizes in a repeat with other kinds of track sizes. This means that grid-template-columns: repeat(auto-fill, 100px auto); would not be allowed. This is a possible mitigation, but doesn't prevent issues where there is a fixed track size outside of the auto repeat.
For example, you can hit similar issues with grid-template-columns: 10px repeat(auto-fill, auto);. If you replace the track definition above with this, you get the same rendering:

So if we go this path, we may also want to consider restricting it further to only allow intrinsic auto repeats on their own, but this seems overly restrictive to me.
Option 2:
Instead of expanding the intrinsic auto repeat once in the first track sizing pass, expand it enough to cover the largest spanning item. Don't divide items by their span size, and place items as normal. This would fix the case mentioned above, but you could end up with different sizes for different intrinsic tracks.
For example, if you had grid-template-columns: repeat(auto-fill, 100px auto auto); in the example above, the first auto would evaluate to 200px and the second would evaluate to 150px. You could solve this by taking the largest of the final intrinsic track sizes (in this case 200px) to determine the number of auto repeats to do.
Option 3:
Instead of dividing by the total span, take each item span, and reduce it based on min(total number of tracks, item span). That means that if your item spans 5 tracks, and there are 3 tracks after expanding the intrinsic auto repeat once, you would reduce its span to 3 and adjust its contribution accordingly. This would fix the case above, but I suspect you can still come up with cases that lead to overflow.
This option, similar to 2, would require you to take the largest final initial track size per type of intrinsic track in the repeat, since you could end up with different sizes based on your track definition and items.
Option 4:
Leave the heuristic as is and accept that there are cases where it doesn't work as well that could lead to overflow.
Any other ideas?
Metadata
Metadata
Assignees
Labels
Type
Projects
Status