LibWeb: Clamp content-based minimum size by limited max track size [GFC]

Progress on https://wpt.live/css/css-grid/grid-items/grid-minimum-size-grid-items-022.html
This commit is contained in:
Aliaksandr Kalenik 2025-03-17 22:46:58 +01:00 committed by Alexander Kalenik
parent ec3c545426
commit 4a7b947c5d
Notes: github-actions[bot] 2025-03-18 14:17:20 +00:00
3 changed files with 86 additions and 9 deletions

View file

@ -2554,18 +2554,44 @@ CSSPixels GridFormattingContext::content_based_minimum_size(GridItem const& item
// The content-based minimum size for a grid item in a given dimension is its specified size suggestion if it exists,
// otherwise its transferred size suggestion if that exists,
// else its content size suggestion, see below.
// In all cases, the size suggestion is additionally clamped by the maximum size in the affected axis, if its definite.
auto maximum_size = CSSPixels::max();
if (auto const& css_maximum_size = get_item_maximum_size(item, dimension); css_maximum_size.is_length()) {
maximum_size = css_maximum_size.length().to_px(item.box);
}
CSSPixels result = 0;
if (auto specified_size_suggestion = this->specified_size_suggestion(item, dimension); specified_size_suggestion.has_value()) {
return min(specified_size_suggestion.value(), maximum_size);
result = specified_size_suggestion.value();
} else {
result = content_size_suggestion(item, dimension);
}
return min(content_size_suggestion(item, dimension), maximum_size);
// However, if in a given dimension the grid item spans only grid tracks that have a fixed max track sizing function, then
// its specified size suggestion and content size suggestion in that dimension (and its input from this dimension to the
// transferred size suggestion in the opposite dimension) are further clamped to less than or equal to the stretch fit into
// the grid areas maximum size in that dimension, as represented by the sum of those grid tracks max track sizing functions
// plus any intervening fixed gutters.
// FIXME: Account for intervening fixed gutters.
auto const& tracks = dimension == GridDimension::Column ? m_grid_columns : m_grid_rows;
auto const& available_size = dimension == GridDimension::Column ? m_available_space->width : m_available_space->height;
auto item_track_index = item.raw_position(dimension);
auto item_track_span = item.span(dimension);
bool spans_only_tracks_with_limited_max_track_sizing_function = true;
CSSPixels sum_of_max_sizing_functions = 0;
for (size_t index = 0; index < item_track_span; index++) {
auto const& track = tracks[item_track_index + index];
if (!track.max_track_sizing_function.is_fixed(available_size)) {
spans_only_tracks_with_limited_max_track_sizing_function = false;
break;
}
sum_of_max_sizing_functions += track.max_track_sizing_function.length_percentage().length().to_px(item.box);
}
if (spans_only_tracks_with_limited_max_track_sizing_function) {
result = min(result, sum_of_max_sizing_functions);
}
// In all cases, the size suggestion is additionally clamped by the maximum size in the affected axis, if its definite.
if (auto const& css_maximum_size = get_item_maximum_size(item, dimension); css_maximum_size.is_length()) {
auto maximum_size = css_maximum_size.length().to_px(item.box);
result = min(result, maximum_size);
}
return result;
}
CSSPixels GridFormattingContext::automatic_minimum_size(GridItem const& item, GridDimension const dimension) const

View file

@ -0,0 +1,29 @@
Viewport <#document> at (0,0) content-size 800x600 children: not-inline
BlockContainer <html> at (0,0) content-size 800x136 [BFC] children: not-inline
BlockContainer <body> at (8,8) content-size 784x120 children: not-inline
Box <div.grid> at (13,13) content-size 50x50 [GFC] children: not-inline
BlockContainer <div#a> at (13,13) content-size 0x25 [BFC] children: inline
frag 0 from TextNode start: 0, length: 10, rect: [13,13 115.625x17] baseline: 13.296875
"XXXXXXXXXX"
TextNode <#text>
BlockContainer <div#b> at (13,38) content-size 0x25 [BFC] children: not-inline
BlockContainer <(anonymous)> at (8,68) content-size 784x0 children: inline
TextNode <#text>
Box <div.grid> at (13,73) content-size 50x50 [GFC] children: not-inline
BlockContainer <div#a> at (18,73) content-size 0x25 [BFC] children: not-inline
BlockContainer <div#b> at (13,98) content-size 10x25 [BFC] children: not-inline
BlockContainer <(anonymous)> at (8,128) content-size 784x0 children: inline
TextNode <#text>
ViewportPaintable (Viewport<#document>) [0,0 800x600]
PaintableWithLines (BlockContainer<HTML>) [0,0 800x136]
PaintableWithLines (BlockContainer<BODY>) [8,8 784x120]
PaintableBox (Box<DIV>.grid) [8,8 60x60]
PaintableWithLines (BlockContainer<DIV>#a) [13,13 0x25] overflow: [13,13 115.625x17]
TextPaintable (TextNode<#text>)
PaintableWithLines (BlockContainer<DIV>#b) [13,38 0x25]
PaintableWithLines (BlockContainer(anonymous)) [8,68 784x0]
PaintableBox (Box<DIV>.grid) [8,68 60x60]
PaintableWithLines (BlockContainer<DIV>#a) [18,73 0x25]
PaintableWithLines (BlockContainer<DIV>#b) [13,98 10x25]
PaintableWithLines (BlockContainer(anonymous)) [8,128 784x0]

View file

@ -0,0 +1,22 @@
<!DOCTYPE html><style>
.grid {
display: grid;
background-color: grey;
border: solid thick;
width: 50px;
height: 50px;
grid-template-rows: 25px 25px;
grid-template-columns: minmax(auto, 0px);
}
.grid>div:nth-child(1) {
color: blue;
background: cyan;
}
.grid>div:nth-child(2) {
background: magenta;
}
</style>
<div class="grid"><div id="a">XXXXXXXXXX</div><div id="b"></div></div>
<div class="grid"><div id="a" style="margin: 0px 5px"></div><div id="b"></div></div>