Open tabatkins opened 6 years ago
From spec, it consider items with span of 1 first, then consider at span of 2 that do not span a track with a flexible sizing function. Which the second row auto get caught.
This is not correct. The second row is auto sized. Flexible sized tracks are those using fr. See https://www.w3.org/TR/css-grid-1/#layout-algorithm
When change second row's auto to 1fr (flexible sizing function), it now has correct behaviour.
Not sure what you mean with "correct" but I guess I've explained it in the previous comment.
This is correct behaviour. Which second row is 1fr
This is incorrect behaviour. Second row is auto
The question is, is second one acceptable result? If it is according to spec, then what kind of scenario it trying to cover? Why do we want content inside item that span multiple tracks to increase height of single track item?
This is not related to total size, I mean individual size. You can check on sample: https://codepen.io/Nness/pen/MrYMzQ?editors=1100#
Then add more <div>push</div>
into <div class="item-side">
I think it makes sense to fix this--to make min-content fit tighter than auto/max-content when possible. We should draft up a change proposal for it for review... @svillar What do you think?
Flagging for f2f. We think the author expectation of this case is fairly clear and the spec would be reasonably straightforward to fix, but at this point the compat impact is very worrying and requires analysis.
The problem seems to be in this line: https://github.com/w3c/csswg-drafts/blob/0dcb036011e9ff870bc3f5de03d53210749ca0b6/css-grid-1/Overview.bs#L4425
It treats all intrinsic max track sizing functions equally instead of prioritizing min-content
vs auto/max-content
.
The CSS Working Group just discussed [css-grid-1] Track Sizing Algorithm question
, and agreed to the following:
RESOLVED: Keep working on a solution for this and take it back to the group
Okay, explaining the current behavior took some doing. Here's a testcase showing it more simply:
<!doctype html>
<div class="container">
<div class="item-head">
<div class=block style="height: 20px;"></div>
</div>
<div class="item-body">
<div class=block style="height: 80px;"></div>
</div>
<div class="item-side">
<div class=block style="height: 150px"></div>
</div>
</div>
<style>
.container {
background-color: #fefefe;
display: grid;
grid-template-columns: 150px auto;
grid-template-rows: min-content auto;
grid-template-areas:
"head side"
"body side";
}
.item-head {
background-color: #d4edda;
grid-area: head;
}
.item-body {
background-color: #fff3cd;
grid-area: body;
}
.item-side {
background-color: #cce5ff;
grid-area: side;
overflow:hidden;
}
.block {
width: 100px;
background: #0002;
}
</style>
As you can see, the blue spanning item gives all of its content's height to the "min-content" track, and none to the "auto" track. This is the opposite of what the OP asks for, and is confusing to boot!
This happens because the blue item is scrollable (via overflow:hidden
). This means it doesn't get an automatic minimum size. In section 11.5, step 3.1, we distribute zero space, as that's the element's "minimum size". Then in step 3.2 we distribute min-content height, which is 150px, to the min-content track only - 150px to distribute, minus 100px of space already present in the track base sizes, means the "min-content" track grows by 50px. Then we're done, all items are considered and all space is distributed.
If the blue item is not scrollable, it has an auto min size of its min-content height, and so step 3.1 distributes that space to both tracks equally. We might still want to prioritize the auto track over the min-content track in this case. But it's not the problem OP is running into.
To address OP's problem, we need to address the fact that the auto track, which has absorbed the spanning item's minimum contribution (0px), isn't absorbing any of the spanning item's min-content contribution (150px). But it's not clear how to do that in the algorithm without breaking other expectations.
Note: The desired behavior is likely more closely represented (in the current algorithm) by this:
grid-template-rows: minmax(auto, min-content) auto;
instead of
grid-template-rows: min-content auto;
Still leaves open the idea of prioritizing auto/max-content tracks over min-content, though, to get it to size tightly around the min-content track rather than distributing the spanner equally.
In the spirit of fr tracks, let spanned auto maximum tracks absorb space over intrinsic minimums?
Possible Idea:
Other Possible idea
I also analyzed the testcase with more detail after the meeting, but forgot to post my thoughts.
Basically, some confusing behavior of grid is that auto
has completely opposite meanings when used as a min track sizing function vs a max track sizing function.
auto
<= min-content
<= max-content
.max-content
, except that it can be stretched at the end of the algorithm. So min-content
<= max-content
<= auto
.The example here uses min-content, auto
, i.e. mimax(min-content, min-content), minmax(auto, auto)
.
This is a somewhat contradictory input: the 1st track is requested to grow more as a minimum, but grow less a maximum. In CSS, minimums win, so that's why basically all of the contribution of the spanning item goes into the min-content
track.
As Tab says, the effects vary a bit depending on the automatic minimum size. Removing the overflow
distributes the size as a minimum contribution, so both rows get half of it since both are intrinsic. With overflow
, the minimum contribution is 0, so the size is distributed as a min-content contribution, and it goes to the 1st track.
I don't think it's possible at this point to change the above. As fantasai says, to get the desired behavior, authors should use a different grid-template-rows
, weakening the min track sizing function of the 1st track, and boosting the min track sizing function of the 2nd track.
grid-template-rows: minmax(auto, min-content) minmax(min-content, auto);
That does the trick when the minimum contribution is 0, but otherwise the size will be distributed equally, just like with
grid-template-rows: min-content minmax(min-content, auto);
grid-template-rows: minmax(auto, min-content) auto;
And it's at this point where I think we can improve the situation by doing what I said in https://github.com/w3c/csswg-drafts/issues/2873#issuecomment-1641000730
The growth limits have been set tight to the size of the non-spanning items, so if we prioritize respecting the limit of a track with a min-content
max track sizing function over respecting the limit of a track with a max-content
or auto
max track sizing function, the extra contribution of the spanning item will go into the 2nd track.
The CSS Working Group just discussed [css-grid-1] Track Sizing Algorithm question
, and agreed to the following:
RESOLVED: when distributing past growth limits, we distribute prioritizing tracks that have max-content max-track-sizing function
Issue copied from original email from Jason.W He (hekylinwork@gmail.com):
In case of following grid.
--- 65% -- | -- 35% -- | min-content --- 65% -- | -- 35% -- | auto --- 65% -- | -- 35% -- |
Two column: 65%, 35% Two row: min-content, auto
template-areas: "head side" "body side"
For row #1's track size, which it use
min-content
to define height of that row. When calculate height, why is row #1 been calculated using items with span of 2?From spec, it consider items with span of 1 first, then consider at span of 2 that do not span a track with a flexible sizing function. Which the second row
auto
get caught.When change second row's auto to 1fr (flexible sizing function), it now has correct behaviour.
I have sample to reproduce this under https://codepen.io/Nness/pen/MrYMzQ?editors=1100#
When increment items inside area
side
. The areahead
's height now resize according toside
.Is this logical and correct behaviour to increase size of single span item by multiple span item?
It make sense to increase total size of multi-span grid track by item span across multiple track. How is that logical to change size of single-span grid track by item span across multiple track?
All the browser I have tested have exactly same result, does that means they all according to spec and have correct behaviour?
If use flexible sizing function is the only way to get this working and it is according to spec, then in which situation we want to use auto to have multiple span item change single span track's height behaviour?