LibWeb: Account for intrinsic width or height in flex base size

In calculating the base size of a flex item, we have a piece of ad-hoc
code that deals with an item that does have an instrinsic aspect ratio,
but not a cross size to resolve that ratio against. In determining the
actual flex item size however, we also take into account the minimum
content width and height, which assumes the box' intrinsic width or
height when available. This would break having an image as a flex item,
which gets stretched to its maximum size within the flex container
instead of the flex item being shrunk to the instrinsic size of the
image.

Fix this by only stretching flex items that do not have an instrinsic
width nor height set.
This commit is contained in:
Jelle Raaijmakers 2024-08-08 17:04:59 +02:00 committed by Sam Atkins
commit 7a783d3a89
Notes: github-actions[bot] 2024-08-09 16:02:41 +00:00
3 changed files with 23 additions and 6 deletions

View file

@ -0,0 +1,15 @@
Viewport <#document> at (0,0) content-size 800x600 children: not-inline
BlockContainer <html> at (0,0) content-size 800x600 [BFC] children: not-inline
BlockContainer <body> at (8,8) content-size 784x8 children: not-inline
Box <div> at (8,8) content-size 784x8 flex-container(row) [FFC] children: not-inline
BlockContainer <(anonymous)> (not painted) [BFC] children: inline
TextNode <#text>
ImageBox <img> at (8,8) content-size 8x8 flex-item children: not-inline
BlockContainer <(anonymous)> (not painted) [BFC] children: inline
TextNode <#text>
ViewportPaintable (Viewport<#document>) [0,0 800x600]
PaintableWithLines (BlockContainer<HTML>) [0,0 800x600]
PaintableWithLines (BlockContainer<BODY>) [8,8 784x8]
PaintableBox (Box<DIV>) [8,8 784x8]
ImagePaintable (ImageBox<IMG>) [8,8 8x8]

View file

@ -0,0 +1,2 @@
<div style="display:flex">
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAIAQMAAAD+wSzIAAAABlBMVEX///+/v7+jQ3Y5AAAADklEQVQI12P4AIX8EAgALgAD/aNpbtEAAAAASUVORK5CYII">

View file

@ -621,19 +621,19 @@ void FlexFormattingContext::determine_flex_base_size_and_hypothetical_main_size(
// in the various helpers that calculate the intrinsic sizes of a flex item,
// e.g. calculate_min_content_main_size().
if (item.used_flex_basis->has<CSS::FlexBasisContent>()) {
if (item.used_flex_basis->has<CSS::FlexBasisContent>())
return calculate_max_content_main_size(item);
}
return calculate_fit_content_main_size(item);
}();
// AD-HOC: This is not mentioned in the spec, but if the item has an aspect ratio,
// we may need to adjust the main size in these ways:
// - using stretch-fit main size if the flex basis is indefinite and there is no cross size to resolve the ratio against.
// AD-HOC: This is not mentioned in the spec, but if the item has an aspect ratio, we may need
// to adjust the main size in these ways:
// - using stretch-fit main size if the flex basis is indefinite, there is no
// intrinsic size and no cross size to resolve the ratio against.
// - in response to cross size min/max constraints.
if (item.box->has_natural_aspect_ratio()) {
if (!item.used_flex_basis_is_definite && !has_definite_cross_size(item)) {
if (!item.used_flex_basis_is_definite && !item.box->has_natural_width() && !item.box->has_natural_height() && !has_definite_cross_size(item)) {
item.flex_base_size = inner_main_size(m_flex_container_state);
}
item.flex_base_size = adjust_main_size_through_aspect_ratio_for_cross_size_min_max_constraints(child_box, item.flex_base_size, computed_cross_min_size(child_box), computed_cross_max_size(child_box));