mirror of
https://github.com/fergalmoran/ladybird.git
synced 2026-01-06 16:45:03 +00:00
LibWeb: Stop treating intrinsic size keywords as auto in CSS heights
This commit introduces proper handling of three intrinsic size keywords when used for CSS heights: - min-content - max-content - fit-content This necessitated a few plumbing changes, since we can't resolve these values without having access to containing block widths. This fixes some visual glitches on https://www.supabase.com/ as well as a number of WPT tests. It also improves the appearance of dialogs.
This commit is contained in:
committed by
Andreas Kling
parent
f093a8af67
commit
fbe9395928
@@ -624,7 +624,7 @@ CSSPixels FormattingContext::tentative_height_for_replaced_element(Box const& bo
|
||||
return 150;
|
||||
|
||||
// FIXME: Handle cases when available_space is not definite.
|
||||
return calculate_inner_height(box, available_space.height, computed_height);
|
||||
return calculate_inner_height(box, available_space, computed_height);
|
||||
}
|
||||
|
||||
CSSPixels FormattingContext::compute_height_for_replaced_element(Box const& box, AvailableSpace const& available_space) const
|
||||
@@ -954,12 +954,12 @@ void FormattingContext::compute_height_for_absolutely_positioned_non_replaced_el
|
||||
auto const& computed_max_height = box.computed_values().max_height();
|
||||
auto constrained_height = unconstrained_height;
|
||||
if (!computed_max_height.is_none()) {
|
||||
auto inner_max_height = calculate_inner_height(box, available_space.height, computed_max_height);
|
||||
auto inner_max_height = calculate_inner_height(box, available_space, computed_max_height);
|
||||
if (inner_max_height < constrained_height.to_px(box))
|
||||
constrained_height = CSS::Length::make_px(inner_max_height);
|
||||
}
|
||||
if (!computed_min_height.is_auto()) {
|
||||
auto inner_min_height = calculate_inner_height(box, available_space.height, computed_min_height);
|
||||
auto inner_min_height = calculate_inner_height(box, available_space, computed_min_height);
|
||||
if (inner_min_height > constrained_height.to_px(box))
|
||||
constrained_height = CSS::Length::make_px(inner_min_height);
|
||||
}
|
||||
@@ -1148,7 +1148,7 @@ void FormattingContext::compute_height_for_absolutely_positioned_non_replaced_el
|
||||
return CSS::Length::make_px(compute_table_box_height_inside_table_wrapper(box, available_space));
|
||||
if (should_treat_height_as_auto(box, available_space))
|
||||
return CSS::Length::make_auto();
|
||||
return CSS::Length::make_px(calculate_inner_height(box, available_space.height, box.computed_values().height()));
|
||||
return CSS::Length::make_px(calculate_inner_height(box, available_space, box.computed_values().height()));
|
||||
}());
|
||||
|
||||
used_height = apply_min_max_height_constraints(used_height);
|
||||
@@ -1614,11 +1614,23 @@ 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, AvailableSize const& available_height, CSS::Size const& height) const
|
||||
CSSPixels FormattingContext::calculate_inner_height(Layout::Box const& box, AvailableSpace const& available_space, CSS::Size const& height) const
|
||||
{
|
||||
VERIFY(!height.is_auto());
|
||||
auto height_of_containing_block = available_height.to_px_or_zero();
|
||||
|
||||
if (height.is_fit_content()) {
|
||||
return calculate_fit_content_height(box, available_space);
|
||||
}
|
||||
if (height.is_max_content()) {
|
||||
return calculate_max_content_height(box, available_space.width.to_px_or_zero());
|
||||
}
|
||||
if (height.is_min_content()) {
|
||||
return calculate_min_content_height(box, available_space.width.to_px_or_zero());
|
||||
}
|
||||
|
||||
auto height_of_containing_block = available_space.height.to_px_or_zero();
|
||||
auto& computed_values = box.computed_values();
|
||||
|
||||
if (computed_values.box_sizing() == CSS::BoxSizing::BorderBox) {
|
||||
auto const& state = m_state.get(box);
|
||||
auto inner_height = height.to_px(box, height_of_containing_block)
|
||||
@@ -1682,7 +1694,7 @@ CSSPixels FormattingContext::calculate_stretch_fit_height(Box const& box, Availa
|
||||
- box_state.border_bottom;
|
||||
}
|
||||
|
||||
bool FormattingContext::should_treat_width_as_auto(Box const& box, AvailableSpace const& available_space)
|
||||
bool FormattingContext::should_treat_width_as_auto(Box const& box, AvailableSpace const& available_space) const
|
||||
{
|
||||
auto const& computed_width = box.computed_values().width();
|
||||
if (computed_width.is_auto())
|
||||
@@ -1693,35 +1705,42 @@ bool FormattingContext::should_treat_width_as_auto(Box const& box, AvailableSpac
|
||||
if (available_space.width.is_indefinite())
|
||||
return true;
|
||||
}
|
||||
// AD-HOC: If the box has a preferred aspect ratio and no natural height,
|
||||
// we treat the width as auto, since it can't be resolved through the ratio.
|
||||
if (computed_width.is_min_content() || computed_width.is_max_content() || computed_width.is_fit_content()) {
|
||||
if (box.has_preferred_aspect_ratio() && !box.has_natural_height())
|
||||
// AD-HOC: If the box has a preferred aspect ratio and an intrinsic keyword for width...
|
||||
if (box.has_preferred_aspect_ratio()
|
||||
&& (computed_width.is_min_content() || computed_width.is_max_content() || computed_width.is_fit_content())) {
|
||||
// If the box has no natural height to resolve the aspect ratio, we treat the width as auto.
|
||||
if (!box.has_natural_height())
|
||||
return true;
|
||||
// If the box has definite height, we can resolve the width through the aspect ratio.
|
||||
if (m_state.get(box).has_definite_height())
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool FormattingContext::should_treat_height_as_auto(Box const& box, AvailableSpace const& available_space)
|
||||
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())
|
||||
return true;
|
||||
|
||||
// https://www.w3.org/TR/css-sizing-3/#valdef-width-min-content
|
||||
// https://www.w3.org/TR/css-sizing-3/#valdef-width-max-content
|
||||
// https://www.w3.org/TR/css-sizing-3/#valdef-width-fit-content
|
||||
// For a box’s block size, unless otherwise specified, this is equivalent to its automatic size.
|
||||
// FIXME: If height is not the block axis size, then we should be concerned with the width instead.
|
||||
if (computed_height.is_min_content() || computed_height.is_max_content() || computed_height.is_fit_content())
|
||||
return true;
|
||||
|
||||
if (box.computed_values().height().contains_percentage()) {
|
||||
if (computed_height.contains_percentage()) {
|
||||
if (available_space.height.is_max_content())
|
||||
return true;
|
||||
if (available_space.height.is_indefinite())
|
||||
return true;
|
||||
}
|
||||
|
||||
// AD-HOC: If the box has a preferred aspect ratio and an intrinsic keyword for height...
|
||||
if (box.has_preferred_aspect_ratio()
|
||||
&& (computed_height.is_min_content() || computed_height.is_max_content() || computed_height.is_fit_content())) {
|
||||
// If the box has no natural width to resolve the aspect ratio, we treat the height as auto.
|
||||
if (!box.has_natural_width())
|
||||
return true;
|
||||
// If the box has definite width, we can resolve the height through the aspect ratio.
|
||||
if (m_state.get(box).has_definite_width())
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user