Skip to content

Commit ccf35a9

Browse files
committed
LibWeb: Derive box baseline from last child *with line boxes*
Before this change, we always derived a box's baseline from its last child, even if the last child didn't have any line boxes inside. This caused baselines to slip further down vertically than expected. There are more baseline alignment issues to fix, but this one was responsible for a fair chunk of trouble. :^)
1 parent 7b3902e commit ccf35a9

File tree

7 files changed

+107
-8
lines changed

7 files changed

+107
-8
lines changed
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
Viewport <#document> at (0,0) content-size 800x600 children: not-inline
2+
BlockContainer <html> at (1,1) content-size 798x600 [BFC] children: not-inline
3+
BlockContainer <body> at (10,10) content-size 780x92.9375 children: inline
4+
line 0 width: 307.140625, height: 92.9375, bottom: 92.9375, baseline: 35
5+
frag 0 from TextNode start: 0, length: 13, rect: [10,31.46875 103.140625x17.46875]
6+
"Hello friends"
7+
frag 1 from BlockContainer start: 0, length: 0, rect: [114.140625,11 202x90.9375]
8+
TextNode <#text>
9+
BlockContainer <div.ib> at (114.140625,11) content-size 202x90.9375 inline-block [BFC] children: not-inline
10+
BlockContainer <div> at (115.140625,12) content-size 200x17.46875 children: inline
11+
line 0 width: 22.546875, height: 17.46875, bottom: 17.46875, baseline: 13.53125
12+
frag 0 from TextNode start: 0, length: 3, rect: [115.140625,12 22.546875x17.46875]
13+
"1st"
14+
TextNode <#text>
15+
BlockContainer <div> at (115.140625,31.46875) content-size 200x17.46875 children: inline
16+
line 0 width: 26.28125, height: 17.46875, bottom: 17.46875, baseline: 13.53125
17+
frag 0 from TextNode start: 0, length: 3, rect: [115.140625,31.46875 26.28125x17.46875]
18+
"2nd"
19+
TextNode <#text>
20+
BlockContainer <div.whee> at (115.140625,50.9375) content-size 200x50 children: not-inline
21+
BlockContainer <(anonymous)> at (114.140625,101.9375) content-size 202x0 children: inline
22+
TextNode <#text>
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
Viewport <#document> at (0,0) content-size 800x600 children: not-inline
2+
BlockContainer <html> at (1,1) content-size 798x600 [BFC] children: not-inline
3+
BlockContainer <body> at (10,10) content-size 780x60.40625 children: inline
4+
line 0 width: 144.375, height: 60.40625, bottom: 60.40625, baseline: 35
5+
frag 0 from TextNode start: 0, length: 13, rect: [10,31.46875 103.140625x17.46875]
6+
"Hello friends"
7+
frag 1 from BlockContainer start: 0, length: 0, rect: [114.140625,11 39.234375x58.40625]
8+
TextNode <#text>
9+
BlockContainer <div.ib> at (114.140625,11) content-size 39.234375x58.40625 inline-block [BFC] children: not-inline
10+
BlockContainer <div> at (115.140625,12) content-size 37.234375x17.46875 children: inline
11+
line 0 width: 22.546875, height: 17.46875, bottom: 17.46875, baseline: 13.53125
12+
frag 0 from TextNode start: 0, length: 3, rect: [115.140625,12 22.546875x17.46875]
13+
"1st"
14+
TextNode <#text>
15+
BlockContainer <div> at (115.140625,31.46875) content-size 37.234375x17.46875 children: inline
16+
line 0 width: 26.28125, height: 17.46875, bottom: 17.46875, baseline: 13.53125
17+
frag 0 from TextNode start: 0, length: 3, rect: [115.140625,31.46875 26.28125x17.46875]
18+
"2nd"
19+
TextNode <#text>
20+
BlockContainer <div.float> at (115.140625,50.9375) content-size 37.234375x17.46875 floating [BFC] children: inline
21+
line 0 width: 37.234375, height: 17.46875, bottom: 17.46875, baseline: 13.53125
22+
frag 0 from TextNode start: 0, length: 5, rect: [115.140625,50.9375 37.234375x17.46875]
23+
"float"
24+
TextNode <#text>
25+
BlockContainer <(anonymous)> at (114.140625,49.9375) content-size 39.234375x0 children: inline
26+
TextNode <#text>
Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
Viewport <#document> at (0,0) content-size 800x600 children: not-inline
2-
BlockContainer <html> at (1,1) content-size 798x135 [BFC] children: inline
3-
line 0 width: 170.96875, height: 135, bottom: 135, baseline: 13.53125
4-
frag 0 from BlockContainer start: 0, length: 0, rect: [2,15.53125 168.96875x119.46875]
5-
BlockContainer <body> at (2,15.53125) content-size 168.96875x119.46875 inline-block [BFC] children: not-inline
6-
BlockContainer <div.hmm> at (3,16.53125) content-size 166.96875x17.46875 children: inline
2+
BlockContainer <html> at (1,1) content-size 798x121.46875 [BFC] children: inline
3+
line 0 width: 170.96875, height: 121.46875, bottom: 121.46875, baseline: 15.53125
4+
frag 0 from BlockContainer start: 0, length: 0, rect: [2,2 168.96875x119.46875]
5+
BlockContainer <body> at (2,2) content-size 168.96875x119.46875 inline-block [BFC] children: not-inline
6+
BlockContainer <div.hmm> at (3,3) content-size 166.96875x17.46875 children: inline
77
line 0 width: 166.96875, height: 17.46875, bottom: 17.46875, baseline: 13.53125
8-
frag 0 from TextNode start: 0, length: 21, rect: [3,16.53125 166.96875x17.46875]
8+
frag 0 from TextNode start: 0, length: 21, rect: [3,3 166.96875x17.46875]
99
"suspiciously tall box"
1010
TextNode <#text>
11-
BlockContainer <(anonymous)> at (2,135) content-size 168.96875x0 children: inline
11+
BlockContainer <(anonymous)> at (2,121.46875) content-size 168.96875x0 children: inline
1212
TextNode <#text>
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<style>
2+
* {
3+
border: 1px solid black;
4+
}
5+
.ib {
6+
display: inline-block;
7+
}
8+
.ib div {
9+
background: pink;
10+
}
11+
.ib div.whee {
12+
width: 200px;
13+
height: 50px;
14+
background: orange;
15+
}
16+
</style><body>Hello friends<div class=ib><div>1st</div><div>2nd</div><div class="whee"></div>
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<style>
2+
* {
3+
border: 1px solid black;
4+
}
5+
.ib {
6+
display: inline-block;
7+
}
8+
.ib div {
9+
background: pink;
10+
}
11+
.ib div.float {
12+
background: orange;
13+
float: left;
14+
}
15+
</style><body>Hello friends<div class=ib><div>1st</div><div>2nd</div><div class="float">float</div>

Userland/Libraries/LibWeb/Layout/FormattingContext.cpp

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1686,6 +1686,24 @@ CSSPixelRect FormattingContext::absolute_content_rect(Box const& box) const
16861686
return rect;
16871687
}
16881688

1689+
Box const* FormattingContext::box_child_to_derive_baseline_from(Box const& box) const
1690+
{
1691+
// To find the baseline of a box, we first look for the last in-flow child with at least one line box.
1692+
auto const* last_box_child = box.last_child_of_type<Box>();
1693+
for (Node const* child = last_box_child; child; child = child->previous_sibling()) {
1694+
if (!child->is_box())
1695+
continue;
1696+
auto& child_box = static_cast<Box const&>(*child);
1697+
if (child_box.is_out_of_flow(*this))
1698+
continue;
1699+
if (m_state.get(child_box).line_boxes.is_empty())
1700+
continue;
1701+
return &child_box;
1702+
}
1703+
// If none of the children has a line box, the baseline is formed by the last in-flow child.
1704+
return last_box_child;
1705+
}
1706+
16891707
CSSPixels FormattingContext::box_baseline(Box const& box) const
16901708
{
16911709
auto const& box_state = m_state.get(box);
@@ -1714,7 +1732,7 @@ CSSPixels FormattingContext::box_baseline(Box const& box) const
17141732
if (!box_state.line_boxes.is_empty())
17151733
return box_state.margin_box_top() + box_state.offset.y() + box_state.line_boxes.last().baseline();
17161734
if (box.has_children() && !box.children_are_inline()) {
1717-
auto const* child_box = box.last_child_of_type<Box>();
1735+
auto const* child_box = box_child_to_derive_baseline_from(box);
17181736
VERIFY(child_box);
17191737
return box_baseline(*child_box);
17201738
}

Userland/Libraries/LibWeb/Layout/FormattingContext.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,8 @@ class FormattingContext {
151151

152152
[[nodiscard]] Optional<CSSPixels> compute_auto_height_for_absolutely_positioned_element(Box const&, AvailableSpace const&, BeforeOrAfterInsideLayout) const;
153153

154+
[[nodiscard]] Box const* box_child_to_derive_baseline_from(Box const&) const;
155+
154156
Type m_type {};
155157

156158
FormattingContext* m_parent { nullptr };

0 commit comments

Comments
 (0)