LibWeb: Resolve "height: auto" using preferred aspect ratio if possible

Fixes https://github.com/LadybirdBrowser/ladybird/issues/2276
This commit is contained in:
Aliaksandr Kalenik 2025-03-14 20:20:34 +01:00 committed by Alexander Kalenik
parent 227b4c38b7
commit 08c155cd3f
Notes: github-actions[bot] 2025-03-15 12:52:15 +00:00
6 changed files with 55 additions and 11 deletions

View file

@ -1439,6 +1439,10 @@ CSSPixels FormattingContext::calculate_fit_content_height(Layout::Box const& box
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())
return *box.natural_width();
@ -1594,8 +1598,12 @@ CSSPixels FormattingContext::calculate_inner_width(Layout::Box const& box, Avail
return width.to_px(box, width_of_containing_block);
}
CSSPixels FormattingContext::calculate_inner_height(Layout::Box const& box, AvailableSpace const& available_space, CSS::Size const& height) const
CSSPixels FormattingContext::calculate_inner_height(Box const& box, AvailableSpace const& available_space, CSS::Size const& height) const
{
if (height.is_auto() && box.has_preferred_aspect_ratio()) {
return m_state.get(box).content_width() / *box.preferred_aspect_ratio();
}
VERIFY(!height.is_auto());
if (height.is_fit_content()) {
@ -1701,8 +1709,12 @@ bool FormattingContext::should_treat_width_as_auto(Box const& box, AvailableSpac
bool FormattingContext::should_treat_height_as_auto(Box const& box, AvailableSpace const& available_space) const
{
auto computed_height = box.computed_values().height();
if (computed_height.is_auto())
if (computed_height.is_auto()) {
auto const& box_state = m_state.get(box);
if (box_state.has_definite_width() && box.has_preferred_aspect_ratio())
return false;
return true;
}
if (computed_height.contains_percentage()) {
if (available_space.height.is_max_content())

View file

@ -76,7 +76,7 @@ public:
CSSPixels calculate_fit_content_width(Layout::Box const&, AvailableSpace const&) const;
CSSPixels calculate_inner_width(Layout::Box const&, AvailableSize const&, CSS::Size const& width) const;
[[nodiscard]] CSSPixels calculate_inner_height(Layout::Box const&, AvailableSpace const&, CSS::Size const& height) const;
[[nodiscard]] CSSPixels calculate_inner_height(Box const&, AvailableSpace const&, CSS::Size const& height) const;
virtual CSSPixels greatest_child_width(Box const&) const;

View file

@ -2438,6 +2438,9 @@ CSSPixels GridFormattingContext::calculate_min_content_contribution(GridItem con
}
auto preferred_size = get_item_preferred_size(item, dimension);
if (dimension == GridDimension::Row && preferred_size.is_auto() && item.box->has_preferred_aspect_ratio()) {
return m_state.get(item.box).content_width() / item.box->preferred_aspect_ratio().value();
}
auto containing_block_size = containing_block_size_for_item(item, dimension);
auto result = item.add_margin_box_sizes(preferred_size.to_px(grid_container(), containing_block_size), dimension);
return min(result, maxium_size);

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 784x50 children: not-inline
Box <div#item> at (8,8) content-size 100x50 [GFC] children: not-inline
BlockContainer <(anonymous)> (not painted) [BFC] children: inline
TextNode <#text>
ImageBox <img> at (8,8) content-size 50x50 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 784x50]
PaintableBox (Box<DIV>#item) [8,8 100x50]
ImagePaintable (ImageBox<IMG>) [8,8 50x50]

View file

@ -1,15 +1,15 @@
Viewport <#document> at (0,0) content-size 800x600 children: not-inline
BlockContainer <html> at (0,0) content-size 800x33 [BFC] children: not-inline
BlockContainer <body> at (8,8) content-size 784x17 children: inline
frag 0 from Box start: 0, length: 0, rect: [8,11 10x10.3125] baseline: 9.953125
Box <div.inline-flex.aspect-ratio> at (8,11) content-size 10x10.3125 flex-container(row) [FFC] children: not-inline
BlockContainer <div.img-wrapper> at (8,7.65625) content-size 10x17 flex-item [BFC] children: inline
frag 0 from ImageBox start: 0, length: 0, rect: [8,10.65625 10x10] baseline: 10
ImageBox <img> at (8,10.65625) content-size 10x10 children: not-inline
frag 0 from Box start: 0, length: 0, rect: [8,8 10x10.3125] baseline: 13.296875
Box <div.inline-flex.aspect-ratio> at (8,8) content-size 10x10.3125 flex-container(row) [FFC] children: not-inline
BlockContainer <div.img-wrapper> at (8,8) content-size 10x10.3125 flex-item [BFC] children: inline
frag 0 from ImageBox start: 0, length: 0, rect: [8,11 10x10] baseline: 10
ImageBox <img> at (8,11) content-size 10x10 children: not-inline
ViewportPaintable (Viewport<#document>) [0,0 800x600]
PaintableWithLines (BlockContainer<HTML>) [0,0 800x33]
PaintableWithLines (BlockContainer<BODY>) [8,8 784x17]
PaintableBox (Box<DIV>.inline-flex.aspect-ratio) [8,11 10x10.3125] overflow: [8,7.65625 10x17]
PaintableWithLines (BlockContainer<DIV>.img-wrapper) [8,7.65625 10x17]
ImagePaintable (ImageBox<IMG>) [8,10.65625 10x10]
PaintableBox (Box<DIV>.inline-flex.aspect-ratio) [8,8 10x10.3125] overflow: [8,8 10x13]
PaintableWithLines (BlockContainer<DIV>.img-wrapper) [8,8 10x10.3125] overflow: [8,8 10x13]
ImagePaintable (ImageBox<IMG>) [8,11 10x10]

View file

@ -0,0 +1,14 @@
<style>
#item {
display: grid;
grid-template-columns: 1fr 1fr;
width: 100px;
outline: 1px solid black;
}
img {
width: 100%;
}
</style>
<div id="item">
<img src="../../../Assets/120.png">
</div>