mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-26 01:20:25 +00:00
LibWeb: Don't use BFC auto height for non-BFC abspos elements
While CSS 2.2 does tell us to use the "auto height for BFC roots" calculation when resolving auto heights for abspos elements, that doesn't make sense for other formatting context roots, e.g flex. In lieu of implementing the entire new absolute positioning model from CSS-POSITION-3, this patch borrows one small nugget from it: using fit-content height as the auto height for non-BFC-root abspos elements.
This commit is contained in:
parent
38a6b7ad3d
commit
c808f6c637
Notes:
sideshowbarker
2024-07-17 03:30:41 +09:00
Author: https://github.com/awesomekling Commit: https://github.com/SerenityOS/serenity/commit/c808f6c637 Pull-request: https://github.com/SerenityOS/serenity/pull/19503
4 changed files with 58 additions and 15 deletions
|
@ -0,0 +1,8 @@
|
|||
Viewport <#document> at (0,0) content-size 800x600 children: not-inline
|
||||
BlockContainer <html> at (1,1) content-size 798x0 [BFC] children: not-inline
|
||||
Box <body> at (9,9) content-size 512.859375x19.46875 positioned flex-container(column) [FFC] children: not-inline
|
||||
BlockContainer <div> at (10,10) content-size 510.859375x17.46875 flex-item [BFC] children: inline
|
||||
line 0 width: 510.859375, height: 17.46875, bottom: 17.46875, baseline: 13.53125
|
||||
frag 0 from TextNode start: 0, length: 60, rect: [10,10 510.859375x17.46875]
|
||||
"Diese Website nutzt Cookies und vergleichbare Funktionen zur"
|
||||
TextNode <#text>
|
|
@ -0,0 +1,20 @@
|
|||
<!DOCTYPE html><style>
|
||||
* {
|
||||
border: 1px solid black;
|
||||
}
|
||||
html {
|
||||
background: white;
|
||||
}
|
||||
body {
|
||||
display: flex;
|
||||
flex-flow: column nowrap;
|
||||
position: absolute;
|
||||
top: 0px;
|
||||
left: 0px;
|
||||
background: pink;
|
||||
}
|
||||
div {
|
||||
min-height: 0px;
|
||||
background: orange;
|
||||
}
|
||||
</style><body><div>Diese Website nutzt Cookies und vergleichbare Funktionen zur
|
|
@ -305,6 +305,22 @@ CSSPixelSize FormattingContext::solve_replaced_size_constraint(CSSPixels input_w
|
|||
return { w, h };
|
||||
}
|
||||
|
||||
Optional<CSSPixels> FormattingContext::compute_auto_height_for_absolutely_positioned_element(Box const& box, AvailableSpace const& available_space, BeforeOrAfterInsideLayout before_or_after_inside_layout) const
|
||||
{
|
||||
// NOTE: CSS 2.2 tells us to use the "auto height for block formatting context roots" here.
|
||||
// That's fine as long as the box is a BFC root.
|
||||
if (creates_block_formatting_context(box)) {
|
||||
if (before_or_after_inside_layout == BeforeOrAfterInsideLayout::Before)
|
||||
return {};
|
||||
return compute_auto_height_for_block_formatting_context_root(box);
|
||||
}
|
||||
|
||||
// NOTE: For anything else, we use the fit-content height.
|
||||
// This should eventually be replaced by the new absolute positioning model:
|
||||
// https://www.w3.org/TR/css-position-3/#abspos-layout
|
||||
return calculate_fit_content_height(box, available_space);
|
||||
}
|
||||
|
||||
// https://www.w3.org/TR/CSS22/visudet.html#root-height
|
||||
CSSPixels FormattingContext::compute_auto_height_for_block_formatting_context_root(Box const& root) const
|
||||
{
|
||||
|
@ -798,10 +814,6 @@ void FormattingContext::compute_height_for_absolutely_positioned_non_replaced_el
|
|||
|
||||
// If all three of top, height, and bottom are auto:
|
||||
if (top.is_auto() && height.is_auto() && bottom.is_auto()) {
|
||||
// (If we haven't done inside layout yet, we can't compute the auto height.)
|
||||
if (before_or_after_inside_layout == BeforeOrAfterInsideLayout::Before)
|
||||
return;
|
||||
|
||||
// First set any auto values for margin-top and margin-bottom to 0,
|
||||
if (margin_top.is_auto())
|
||||
margin_top = CSS::Length::make_px(0);
|
||||
|
@ -813,7 +825,10 @@ void FormattingContext::compute_height_for_absolutely_positioned_non_replaced_el
|
|||
top = CSS::Length::make_px(static_position.y());
|
||||
|
||||
// and finally apply rule number three below.
|
||||
height = CSS::Size::make_px(compute_auto_height_for_block_formatting_context_root(box));
|
||||
auto maybe_height = compute_auto_height_for_absolutely_positioned_element(box, available_space, before_or_after_inside_layout);
|
||||
if (!maybe_height.has_value())
|
||||
return;
|
||||
height = CSS::Size::make_px(maybe_height.value());
|
||||
solve_for_bottom();
|
||||
}
|
||||
|
||||
|
@ -853,12 +868,11 @@ void FormattingContext::compute_height_for_absolutely_positioned_non_replaced_el
|
|||
|
||||
// 1. If top and height are auto and bottom is not auto,
|
||||
if (top.is_auto() && height.is_auto() && !bottom.is_auto()) {
|
||||
// (If we haven't done inside layout yet, we can't compute the auto height.)
|
||||
if (before_or_after_inside_layout == BeforeOrAfterInsideLayout::Before)
|
||||
return;
|
||||
|
||||
// then the height is based on the Auto heights for block formatting context roots,
|
||||
height = CSS::Size::make_px(compute_auto_height_for_block_formatting_context_root(box));
|
||||
auto maybe_height = compute_auto_height_for_absolutely_positioned_element(box, available_space, before_or_after_inside_layout);
|
||||
if (!maybe_height.has_value())
|
||||
return;
|
||||
height = CSS::Size::make_px(maybe_height.value());
|
||||
|
||||
// and solve for top.
|
||||
solve_for_top();
|
||||
|
@ -875,12 +889,11 @@ void FormattingContext::compute_height_for_absolutely_positioned_non_replaced_el
|
|||
|
||||
// 3. If height and bottom are auto and top is not auto,
|
||||
else if (height.is_auto() && bottom.is_auto() && !top.is_auto()) {
|
||||
// (If we haven't done inside layout yet, we can't compute the auto height.)
|
||||
if (before_or_after_inside_layout == BeforeOrAfterInsideLayout::Before)
|
||||
return;
|
||||
|
||||
// then the height is based on the Auto heights for block formatting context roots,
|
||||
height = CSS::Size::make_px(compute_auto_height_for_block_formatting_context_root(box));
|
||||
auto maybe_height = compute_auto_height_for_absolutely_positioned_element(box, available_space, before_or_after_inside_layout);
|
||||
if (!maybe_height.has_value())
|
||||
return;
|
||||
height = CSS::Size::make_px(maybe_height.value());
|
||||
|
||||
// and solve for bottom.
|
||||
solve_for_bottom();
|
||||
|
|
|
@ -146,6 +146,8 @@ protected:
|
|||
void compute_height_for_absolutely_positioned_non_replaced_element(Box const&, AvailableSpace const&, BeforeOrAfterInsideLayout);
|
||||
void compute_height_for_absolutely_positioned_replaced_element(Box const&, AvailableSpace const&, BeforeOrAfterInsideLayout);
|
||||
|
||||
[[nodiscard]] Optional<CSSPixels> compute_auto_height_for_absolutely_positioned_element(Box const&, AvailableSpace const&, BeforeOrAfterInsideLayout) const;
|
||||
|
||||
Type m_type {};
|
||||
|
||||
FormattingContext* m_parent { nullptr };
|
||||
|
|
Loading…
Reference in a new issue