Skip to content

Commit

Permalink
LibWeb: Account for absolutely positioned table wrappers
Browse files Browse the repository at this point in the history
Table wrappers don't quite behave the same as most elements, in that
their computed height and width are not meant to be used for layout.
Instead, we now calculate suitable widths and heights based on the
contents of the table wrapper when performing absolute layout.

Fixes the layout of
https://wpt.live/css/css-position/position-absolute-center-007.html
  • Loading branch information
implicitfield authored and awesomekling committed Mar 7, 2024
1 parent 096ddb0 commit 0243278
Show file tree
Hide file tree
Showing 6 changed files with 328 additions and 183 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
Viewport <#document> at (0,0) content-size 800x600 children: not-inline
BlockContainer <html> at (8,8) content-size 784x532 [BFC] children: not-inline
BlockContainer <body> at (16,16) content-size 768x516 children: not-inline
Box <div.container> at (24,24) content-size 500x500 positioned flex-container(row) [FFC] children: not-inline
BlockContainer <(anonymous)> (not painted) [BFC] children: inline
TextNode <#text>
TableWrapper <(anonymous)> at (24,199) content-size 100x150 positioned [BFC] children: not-inline
Box <div.table.left> at (27,202) content-size 94x144 table-box [TFC] children: not-inline
BlockContainer <(anonymous)> (not painted) [BFC] children: inline
TextNode <#text>
TableWrapper <(anonymous)> at (424,199) content-size 100x150 positioned [BFC] children: not-inline
Box <div.table.right> at (427,202) content-size 94x144 table-box [TFC] children: not-inline
BlockContainer <(anonymous)> (not painted) [BFC] children: inline
TextNode <#text>
TableWrapper <(anonymous)> at (199,24) content-size 150x100 positioned [BFC] children: not-inline
Box <div.table.top> at (202,27) content-size 144x94 table-box [TFC] children: not-inline
BlockContainer <(anonymous)> (not painted) [BFC] children: inline
TextNode <#text>
TableWrapper <(anonymous)> at (199,424) content-size 150x100 positioned [BFC] children: not-inline
Box <div.table.bottom> at (202,427) content-size 144x94 table-box [TFC] children: not-inline
BlockContainer <(anonymous)> (not painted) [BFC] children: inline
TextNode <#text>
BlockContainer <(anonymous)> at (16,532) content-size 768x0 children: inline
TextNode <#text>

ViewportPaintable (Viewport<#document>) [0,0 800x600]
PaintableWithLines (BlockContainer<HTML>) [5,5 790x538]
PaintableWithLines (BlockContainer<BODY>) [13,13 774x522]
PaintableBox (Box<DIV>.container) [21,21 506x506]
PaintableWithLines (TableWrapper(anonymous)) [24,199 100x150]
PaintableBox (Box<DIV>.table.left) [24,199 100x150]
PaintableWithLines (TableWrapper(anonymous)) [424,199 100x150]
PaintableBox (Box<DIV>.table.right) [424,199 100x150]
PaintableWithLines (TableWrapper(anonymous)) [199,24 150x100]
PaintableBox (Box<DIV>.table.top) [199,24 150x100]
PaintableWithLines (TableWrapper(anonymous)) [199,424 150x100]
PaintableBox (Box<DIV>.table.bottom) [199,424 150x100]
PaintableWithLines (BlockContainer(anonymous)) [16,532 768x0]
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
<!DOCTYPE html>
<style>
* {
margin: 5px;
padding: 0;
border: 3px solid black;
}
.container {
display: flex;
position: relative;
width: 500px;
height: 500px;
}
.table {
display: table;
position: absolute;
background: green;
margin: auto;
}
.right {
top: 0;
bottom: 0;
right: 0;
width: 100px;
height: 150px;
}
.left {
top: 0;
bottom: 0;
width: 100px;
height: 150px;
}
.top {
left: 0;
right: 0;
width: 150px;
height: 100px;
}
.bottom {
bottom: 0;
left: 0;
right: 0;
width: 150px;
height: 100px;
}
</style>
<div class=container>
<div class="table left"></div>
<div class="table right"></div>
<div class="table top"></div>
<div class="table bottom"></div>
</div>
42 changes: 0 additions & 42 deletions Userland/Libraries/LibWeb/Layout/BlockFormattingContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -410,48 +410,6 @@ void BlockFormattingContext::compute_width_for_block_level_replaced_element_in_n
box_state.padding_right = padding_right;
}

CSSPixels BlockFormattingContext::compute_table_box_width_inside_table_wrapper(Box const& box, AvailableSpace const& available_space)
{
// 17.5.2
// Table wrapper width should be equal to width of table box it contains

auto const& computed_values = box.computed_values();

auto width_of_containing_block = available_space.width.to_px_or_zero();

auto zero_value = CSS::Length::make_px(0);

auto margin_left = computed_values.margin().left().resolved(box, width_of_containing_block);
auto margin_right = computed_values.margin().right().resolved(box, width_of_containing_block);

// If 'margin-left', or 'margin-right' are computed as 'auto', their used value is '0'.
if (margin_left.is_auto())
margin_left = zero_value;
if (margin_right.is_auto())
margin_right = zero_value;

// table-wrapper can't have borders or paddings but it might have margin taken from table-root.
auto available_width = width_of_containing_block - margin_left.to_px(box) - margin_right.to_px(box);

LayoutState throwaway_state(&m_state);
auto context = create_independent_formatting_context_if_needed(throwaway_state, box);
VERIFY(context);
context->run(box, LayoutMode::IntrinsicSizing, m_state.get(box).available_inner_space_or_constraints_from(available_space));

Optional<Box const&> table_box;
box.for_each_in_subtree_of_type<Box>([&](Box const& child_box) {
if (child_box.display().is_table_inside()) {
table_box = child_box;
return IterationDecision::Break;
}
return IterationDecision::Continue;
});
VERIFY(table_box.has_value());

auto table_used_width = throwaway_state.get(*table_box).border_box_width();
return available_space.width.is_definite() ? min(table_used_width, available_width) : table_used_width;
}

void BlockFormattingContext::compute_height(Box const& box, AvailableSpace const& available_space)
{
auto const& computed_values = box.computed_values();
Expand Down
2 changes: 0 additions & 2 deletions Userland/Libraries/LibWeb/Layout/BlockFormattingContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,6 @@ class BlockFormattingContext : public FormattingContext {

void compute_width_for_block_level_replaced_element_in_normal_flow(Box const&, AvailableSpace const&);

CSSPixels compute_table_box_width_inside_table_wrapper(Box const&, AvailableSpace const&);

void layout_viewport(LayoutMode, AvailableSpace const&);

void layout_block_level_children(BlockContainer const&, LayoutMode, AvailableSpace const&);
Expand Down
Loading

0 comments on commit 0243278

Please sign in to comment.