LibWeb: Fix grid layout for replaced items with percentage max-width
Some checks are pending
CI / macOS, arm64, Sanitizer, Clang (push) Waiting to run
CI / Linux, x86_64, Fuzzers, Clang (push) Waiting to run
CI / Linux, x86_64, Sanitizer, GNU (push) Waiting to run
CI / Linux, x86_64, Sanitizer, Clang (push) Waiting to run
Package the js repl as a binary artifact / Linux, arm64 (push) Waiting to run
Package the js repl as a binary artifact / macOS, arm64 (push) Waiting to run
Package the js repl as a binary artifact / Linux, x86_64 (push) Waiting to run
Run test262 and test-wasm / run_and_update_results (push) Waiting to run
Lint Code / lint (push) Waiting to run
Label PRs with merge conflicts / auto-labeler (push) Waiting to run
Push notes / build (push) Waiting to run

CSS grid specification states that for grid items with a replaced
element and a percentage preferred size or maximum size, the percentage
should be resolved against 0 during content-based minimum size
calculation. This makes sense, as it prevents replaced items from
overshooting their grid track while intrinsic track sizes are
calculated, and allows later track size resolution steps to scale
replaced items to fit their grid track.
This commit is contained in:
Aliaksandr Kalenik 2025-08-09 16:28:26 +02:00 committed by Andreas Kling
commit 652a457f52
Notes: github-actions[bot] 2025-08-10 09:07:59 +00:00
4 changed files with 42 additions and 7 deletions

View file

@ -1442,10 +1442,6 @@ CSSPixels FormattingContext::calculate_fit_content_height(Layout::Box const& box
CSSPixels FormattingContext::calculate_min_content_width(Layout::Box const& box) const CSSPixels FormattingContext::calculate_min_content_width(Layout::Box const& box) const
{ {
if (box.is_replaced_box() && box.computed_values().width().is_percentage()) {
return 0;
}
if (box.has_natural_width()) if (box.has_natural_width())
return *box.natural_width(); return *box.natural_width();

View file

@ -2605,9 +2605,21 @@ CSSPixels GridFormattingContext::content_based_minimum_size(GridItem const& item
} }
// In all cases, the size suggestion is additionally clamped by the maximum size in the affected axis, if its definite. // 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 = item.maximum_size(dimension); css_maximum_size.is_length()) { auto const& maximum_size = item.maximum_size(dimension);
auto maximum_size = css_maximum_size.length().to_px(item.box); if (maximum_size.is_length()) {
result = min(result, maximum_size); auto maximum_size_px = maximum_size.length().to_px(item.box);
result = min(result, maximum_size_px);
}
// If the item is a compressible replaced element, and has a definite preferred size or maximum size in the relevant axis,
// the size suggestion is capped by those sizes; for this purpose, any indefinite percentages in these sizes are resolved
// against zero (and considered definite).
// FIXME: "compressible replaced element" includes more elements than is_replaced_box().
auto const& preferred_size = item.preferred_size(dimension);
if (item.box->is_replaced_box() && (preferred_size.is_percentage() || maximum_size.is_percentage())) {
// NOTE: Implements "for this purpose, any indefinite percentages in these sizes are resolved
// against zero (and considered definite)." part.
result = 0;
} }
return result; return result;

View file

@ -0,0 +1,16 @@
Viewport <#document> at (0,0) content-size 800x600 children: not-inline
BlockContainer <html> at (0,0) content-size 800x66 [BFC] children: not-inline
BlockContainer <body> at (8,8) content-size 100x50 children: not-inline
Box <div> at (8,8) content-size 100x50 [GFC] children: not-inline
ImageBox <img> at (8,8) content-size 50x50 children: not-inline
ImageBox <img> at (58,8) content-size 50x50 children: not-inline
ViewportPaintable (Viewport<#document>) [0,0 800x600]
PaintableWithLines (BlockContainer<HTML>) [0,0 800x66]
PaintableWithLines (BlockContainer<BODY>) [8,8 100x50]
PaintableBox (Box<DIV>) [8,8 100x50]
ImagePaintable (ImageBox<IMG>) [8,8 50x50]
ImagePaintable (ImageBox<IMG>) [58,8 50x50]
SC for Viewport<#document> [0,0 800x600] [children: 1] (z-index: auto)
SC for BlockContainer<HTML> [0,0 800x66] [children: 0] (z-index: auto)

View file

@ -0,0 +1,11 @@
<!doctype html><style>
* { outline: 1px solid black; }
body { width: 100px; }
div {
grid-template-columns: auto auto;
display: grid;
}
img {
max-width: 100%;
}
</style><body><div><img src="../../../Assets/120.png"><img src="../../../Assets/120.png">