mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-08-26 04:07:51 +00:00
LibWeb: Fix "box-sizing: border-box" resolution for abspos items
The `calculate_inner_width()` and `calculate_inner_height()` resolve percentage paddings using the width returned by `containing_block_width_for()`. However, this function does not account for grids where the containing block is defined by the grid area to which an item belongs. This change fixes the issue by modifying `calculate_inner_width()` and `calculate_inner_height()` to use the already resolved paddings from the layout state. Corresponding changes ensure that paddings are resolved and saved in the state before box-sizing is handled. As a side effect, this change also improves abspos layout for BFC where now paddings are resolved using padding box of containing block instead of content box of containing block.
This commit is contained in:
parent
805b0fed13
commit
5f74da6ae8
Notes:
github-actions[bot]
2024-09-17 05:57:08 +00:00
Author: https://github.com/kalenikaliaksandr
Commit: 5f74da6ae8
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/1410
7 changed files with 105 additions and 31 deletions
|
@ -667,13 +667,14 @@ void FormattingContext::compute_width_for_absolutely_positioned_non_replaced_ele
|
|||
auto width_of_containing_block = available_space.width.to_px_or_zero();
|
||||
auto const& computed_values = box.computed_values();
|
||||
auto zero_value = CSS::Length::make_px(0);
|
||||
auto& box_state = m_state.get_mutable(box);
|
||||
|
||||
auto margin_left = CSS::Length::make_auto();
|
||||
auto margin_right = CSS::Length::make_auto();
|
||||
auto const border_left = computed_values.border_left().width;
|
||||
auto const border_right = computed_values.border_right().width;
|
||||
auto const padding_left = computed_values.padding().left().to_px(box, width_of_containing_block);
|
||||
auto const padding_right = computed_values.padding().right().to_px(box, width_of_containing_block);
|
||||
auto const padding_left = box_state.padding_left;
|
||||
auto const padding_right = box_state.padding_right;
|
||||
|
||||
auto computed_left = computed_values.inset().left();
|
||||
auto computed_right = computed_values.inset().right();
|
||||
|
@ -835,14 +836,11 @@ void FormattingContext::compute_width_for_absolutely_positioned_non_replaced_ele
|
|||
}
|
||||
}
|
||||
|
||||
auto& box_state = m_state.get_mutable(box);
|
||||
box_state.set_content_width(used_width.to_px(box));
|
||||
box_state.inset_left = left;
|
||||
box_state.inset_right = right;
|
||||
box_state.margin_left = margin_left.to_px(box);
|
||||
box_state.margin_right = margin_right.to_px(box);
|
||||
box_state.padding_left = padding_left;
|
||||
box_state.padding_right = padding_right;
|
||||
}
|
||||
|
||||
void FormattingContext::compute_width_for_absolutely_positioned_replaced_element(Box const& box, AvailableSpace const& available_space)
|
||||
|
@ -962,7 +960,7 @@ void FormattingContext::compute_height_for_absolutely_positioned_non_replaced_el
|
|||
auto top = box.computed_values().inset().top();
|
||||
auto bottom = box.computed_values().inset().bottom();
|
||||
|
||||
auto width_of_containing_block = containing_block_width_for(box);
|
||||
auto width_of_containing_block = available_space.width.to_px_or_zero();
|
||||
auto height_of_containing_block = available_space.height.to_px_or_zero();
|
||||
|
||||
enum class ClampToZero {
|
||||
|
@ -970,15 +968,16 @@ void FormattingContext::compute_height_for_absolutely_positioned_non_replaced_el
|
|||
Yes,
|
||||
};
|
||||
|
||||
auto& state = m_state.get(box);
|
||||
auto try_compute_height = [&](CSS::Length height) -> CSS::Length {
|
||||
auto solve_for = [&](CSS::Length length, ClampToZero clamp_to_zero = ClampToZero::No) {
|
||||
auto unclamped_value = height_of_containing_block
|
||||
- top.to_px(box, height_of_containing_block)
|
||||
- margin_top.to_px(box, width_of_containing_block)
|
||||
- box.computed_values().border_top().width
|
||||
- box.computed_values().padding().top().to_px(box, width_of_containing_block)
|
||||
- state.padding_top
|
||||
- apply_min_max_height_constraints(height).to_px(box)
|
||||
- box.computed_values().padding().bottom().to_px(box, width_of_containing_block)
|
||||
- state.padding_bottom
|
||||
- box.computed_values().border_bottom().width
|
||||
- margin_bottom.to_px(box, width_of_containing_block)
|
||||
- bottom.to_px(box, height_of_containing_block)
|
||||
|
@ -1157,8 +1156,6 @@ void FormattingContext::compute_height_for_absolutely_positioned_non_replaced_el
|
|||
box_state.inset_bottom = bottom.to_px(box, height_of_containing_block);
|
||||
box_state.margin_top = margin_top.to_px(box, width_of_containing_block);
|
||||
box_state.margin_bottom = margin_bottom.to_px(box, width_of_containing_block);
|
||||
box_state.padding_top = box.computed_values().padding().top().to_px(box, width_of_containing_block);
|
||||
box_state.padding_bottom = box.computed_values().padding().bottom().to_px(box, width_of_containing_block);
|
||||
}
|
||||
|
||||
// NOTE: This is different from content_box_rect_in_ancestor_coordinate_space() as this does *not* follow the containing block chain up, but rather the parent() chain.
|
||||
|
@ -1241,6 +1238,12 @@ void FormattingContext::layout_absolutely_positioned_element(Box const& box, Ava
|
|||
box_state.border_top = box.computed_values().border_top().width;
|
||||
box_state.border_bottom = box.computed_values().border_bottom().width;
|
||||
|
||||
auto const containing_block_width = available_space.width.to_px_or_zero();
|
||||
box_state.padding_left = box.computed_values().padding().left().to_px(box, containing_block_width);
|
||||
box_state.padding_right = box.computed_values().padding().right().to_px(box, containing_block_width);
|
||||
box_state.padding_top = box.computed_values().padding().top().to_px(box, containing_block_width);
|
||||
box_state.padding_bottom = box.computed_values().padding().bottom().to_px(box, containing_block_width);
|
||||
|
||||
compute_width_for_absolutely_positioned_element(box, available_space);
|
||||
|
||||
// NOTE: We compute height before *and* after doing inside layout.
|
||||
|
@ -1625,14 +1628,12 @@ CSSPixels FormattingContext::calculate_inner_width(Layout::Box const& box, Avail
|
|||
|
||||
auto& computed_values = box.computed_values();
|
||||
if (computed_values.box_sizing() == CSS::BoxSizing::BorderBox) {
|
||||
auto const padding_left = computed_values.padding().left().resolved(box, width_of_containing_block);
|
||||
auto const padding_right = computed_values.padding().right().resolved(box, width_of_containing_block);
|
||||
|
||||
auto const& state = m_state.get(box);
|
||||
auto inner_width = width.to_px(box, width_of_containing_block)
|
||||
- computed_values.border_left().width
|
||||
- padding_left.to_px(box)
|
||||
- state.padding_left
|
||||
- computed_values.border_right().width
|
||||
- padding_right.to_px(box);
|
||||
- state.padding_right;
|
||||
return max(inner_width, 0);
|
||||
}
|
||||
|
||||
|
@ -1645,16 +1646,12 @@ CSSPixels FormattingContext::calculate_inner_height(Layout::Box const& box, Avai
|
|||
auto height_of_containing_block = available_height.to_px_or_zero();
|
||||
auto& computed_values = box.computed_values();
|
||||
if (computed_values.box_sizing() == CSS::BoxSizing::BorderBox) {
|
||||
auto width_of_containing_block = containing_block_width_for(box);
|
||||
|
||||
auto const padding_top = computed_values.padding().top().resolved(box, width_of_containing_block);
|
||||
auto const padding_bottom = computed_values.padding().bottom().resolved(box, width_of_containing_block);
|
||||
|
||||
auto const& state = m_state.get(box);
|
||||
auto inner_height = height.to_px(box, height_of_containing_block)
|
||||
- computed_values.border_top().width
|
||||
- padding_top.to_px(box)
|
||||
- state.padding_top
|
||||
- computed_values.border_bottom().width
|
||||
- padding_bottom.to_px(box);
|
||||
- state.padding_bottom;
|
||||
return max(inner_height, 0);
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue