LibWeb: Collapse top and bottom margin of empty sibling blocks
Margin collapsing is a bit confusing, but if I understand correctly, when collapsing a box's top margin with the vertically adjacent sibling box above, we should "skip over" empty (0-height) boxes and collapse their margin with *their* vertically adjacent sibling box above, etc. Iterating until we hit the first non-empty in-flow block. This pulls up the bottom part of the face on ACID2. :^)
This commit is contained in:
parent
e50fa413cb
commit
9576f6b1d4
Notes:
sideshowbarker
2024-07-19 05:20:44 +09:00
Author: https://github.com/awesomekling Commit: https://github.com/SerenityOS/serenity/commit/9576f6b1d42
1 changed files with 14 additions and 10 deletions
|
@ -625,30 +625,34 @@ void LayoutBlock::place_block_level_non_replaced_element_in_normal_flow(LayoutBl
|
|||
float y = box.margin_box(*this).top
|
||||
+ box.offset.top.to_px(*this);
|
||||
|
||||
// NOTE: Empty (0-height) preceding siblings have their margins collapsed with *their* preceding sibling, etc.
|
||||
float collapsed_bottom_margin_of_preceding_siblings = 0;
|
||||
|
||||
auto* relevant_sibling = block.previous_sibling();
|
||||
while (relevant_sibling != nullptr) {
|
||||
if (!relevant_sibling->is_absolutely_positioned() && !relevant_sibling->is_floating())
|
||||
break;
|
||||
if (!relevant_sibling->is_absolutely_positioned() && !relevant_sibling->is_floating()) {
|
||||
collapsed_bottom_margin_of_preceding_siblings = max(collapsed_bottom_margin_of_preceding_siblings, relevant_sibling->box_model().margin.bottom.to_px(*relevant_sibling));
|
||||
if (relevant_sibling->height() > 0)
|
||||
break;
|
||||
}
|
||||
relevant_sibling = relevant_sibling->previous_sibling();
|
||||
}
|
||||
|
||||
if (relevant_sibling) {
|
||||
auto& sibling_box = relevant_sibling->box_model();
|
||||
y += relevant_sibling->effective_offset().y() + relevant_sibling->height();
|
||||
|
||||
// Collapse top margin with bottom margin of previous sibling if necessary
|
||||
float previous_sibling_margin_bottom = sibling_box.margin.bottom.to_px(*relevant_sibling);
|
||||
// Collapse top margin with bottom margin of preceding siblings if needed
|
||||
float my_margin_top = box.margin.top.to_px(*this);
|
||||
|
||||
if (my_margin_top < 0 || previous_sibling_margin_bottom < 0) {
|
||||
if (my_margin_top < 0 || collapsed_bottom_margin_of_preceding_siblings < 0) {
|
||||
// Negative margins present.
|
||||
float largest_negative_margin = -min(my_margin_top, previous_sibling_margin_bottom);
|
||||
float largest_positive_margin = (my_margin_top < 0 && previous_sibling_margin_bottom < 0) ? 0 : max(my_margin_top, previous_sibling_margin_bottom);
|
||||
float largest_negative_margin = -min(my_margin_top, collapsed_bottom_margin_of_preceding_siblings);
|
||||
float largest_positive_margin = (my_margin_top < 0 && collapsed_bottom_margin_of_preceding_siblings < 0) ? 0 : max(my_margin_top, collapsed_bottom_margin_of_preceding_siblings);
|
||||
float final_margin = largest_positive_margin - largest_negative_margin;
|
||||
y += final_margin - my_margin_top;
|
||||
} else if (previous_sibling_margin_bottom > my_margin_top) {
|
||||
} else if (collapsed_bottom_margin_of_preceding_siblings > my_margin_top) {
|
||||
// Sibling's margin is larger than mine, adjust so we use sibling's.
|
||||
y += previous_sibling_margin_bottom - my_margin_top;
|
||||
y += collapsed_bottom_margin_of_preceding_siblings - my_margin_top;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue