Skip to content

Commit 8039419

Browse files
tcl3awesomekling
authored andcommitted
LibWeb: Account for floats when computing IFC abspos static position
Previously, when no previous sibling has a line box fragment, the static position for inline-level elements defaulted to (0, 0), ignoring float intrusion into the line box. We now use `leftmost_inline_offset_at()` so the hypothetical box is placed on the float-shortened line.
1 parent bd046f4 commit 8039419

5 files changed

Lines changed: 87 additions & 1 deletion

File tree

Libraries/LibWeb/Layout/InlineFormattingContext.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -582,8 +582,9 @@ StaticPositionRect InlineFormattingContext::calculate_static_position_rect(Box c
582582
// We need to position the box...
583583
// ...below the last fragment, if the display-outside value (before box type transformation) is block.
584584
// ...at the top right corner of the last fragment otherwise.
585+
auto is_block_outside = box.display_before_box_type_transformation().is_block_outside();
585586
if (last_fragment) {
586-
if (box.display_before_box_type_transformation().is_block_outside()) {
587+
if (is_block_outside) {
587588
// Display-outside value is block => position below
588589
position.set_x(0);
589590
position.set_y(last_fragment->offset().y() + last_fragment->height());
@@ -592,6 +593,10 @@ StaticPositionRect InlineFormattingContext::calculate_static_position_rect(Box c
592593
position.set_x(last_fragment->offset().x() + last_fragment->width());
593594
position.set_y(last_fragment->offset().y());
594595
}
596+
} else if (!is_block_outside) {
597+
// No preceding sibling has a line box fragment (e.g. only floats and collapsed whitespace precede this box).
598+
// For inline-level elements, the static position must account for float intrusion into the line box.
599+
position.set_x(leftmost_inline_offset_at(0));
595600
}
596601

597602
return { .rect = { position, { 0, 0 } } };
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
Viewport <#document> at [0,0] [0+0+0 800 0+0+0] [0+0+0 600 0+0+0] [BFC] children: not-inline
2+
BlockContainer <html> at [0,0] [0+0+0 800 0+0+0] [0+0+0 216 0+0+0] [BFC] children: not-inline
3+
BlockContainer <body> at [8,8] [8+0+0 784 0+0+8] [8+0+0 200 0+0+8] children: not-inline
4+
BlockContainer <div#wrapper> at [8,8] positioned [0+0+0 400 0+0+384] [0+0+0 200 0+0+0] children: inline
5+
TextNode <#text> (not painted)
6+
BlockContainer <div#float> at [8,8] floating [0+0+0 100 0+0+0] [0+0+0 200 0+0+0] [BFC] children: not-inline
7+
TextNode <#text> (not painted)
8+
BlockContainer <div#abspos> at [108,8] positioned [0+0+0 50 0+0+0] [0+0+0 50 0+0+0] [BFC] children: not-inline
9+
TextNode <#text> (not painted)
10+
BlockContainer <(anonymous)> at [8,208] [0+0+0 784 0+0+0] [0+0+0 0 0+0+0] children: inline
11+
TextNode <#text> (not painted)
12+
13+
ViewportPaintable (Viewport<#document>) [0,0 800x600]
14+
PaintableWithLines (BlockContainer<HTML>) [0,0 800x216]
15+
PaintableWithLines (BlockContainer<BODY>) [8,8 784x200]
16+
PaintableWithLines (BlockContainer<DIV>#wrapper) [8,8 400x200]
17+
PaintableWithLines (BlockContainer<DIV>#float) [8,8 100x200]
18+
PaintableWithLines (BlockContainer<DIV>#abspos) [108,8 50x50]
19+
PaintableWithLines (BlockContainer(anonymous)) [8,208 784x0]
20+
21+
SC for Viewport<#document> [0,0 800x600] [children: 1] (z-index: auto)
22+
SC for BlockContainer<HTML> [0,0 800x216] [children: 0] (z-index: auto)
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<!DOCTYPE html>
2+
<style>
3+
#wrapper {
4+
position: relative;
5+
width: 400px;
6+
height: 200px;
7+
}
8+
#float {
9+
float: left;
10+
width: 100px;
11+
height: 200px;
12+
background: blue;
13+
}
14+
#abspos {
15+
display: inline-block;
16+
position: absolute;
17+
width: 50px;
18+
height: 50px;
19+
background: green;
20+
}
21+
</style>
22+
<div id="wrapper">
23+
<div id="float"></div>
24+
<div id="abspos"></div>
25+
</div>
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<!DOCTYPE html>
2+
<link rel="help" href="https://drafts.csswg.org/css2/visudet.html#abs-non-replaced-width" />
3+
<link rel="match" href="../../../../../expected/wpt-import/css/css-position/static-position/../../reference/ref-filled-green-100px-square-only.html">
4+
<meta name="assert" content="Tests the static position of inline-level absolute-positioned elements, with combinations of float, direction, and text-align." />
5+
<style>
6+
#container { position: relative; background: red; width: 100px; height: 100px; }
7+
#container > div { background: green; }
8+
#inflow { height: 50px; }
9+
#float { float: left; width: 50px; height: 50px; }
10+
#abs { display: inline; position: absolute; width: 50px; height: 50px; }
11+
</style>
12+
<p>Test passes if there is a filled green square.</p>
13+
<div id=container style="direction: ltr; text-align: left;">
14+
<div id=inflow></div>
15+
<div id=float style="float: left;"></div>
16+
<div id=abs style="transform: translateX(0%);"></div>
17+
</div>
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<!DOCTYPE html>
2+
<link rel="help" href="https://drafts.csswg.org/css2/visudet.html#abs-non-replaced-width" />
3+
<link rel="match" href="../../../../../expected/wpt-import/css/css-position/static-position/../../reference/ref-filled-green-100px-square-only.html">
4+
<meta name="assert" content="Tests the static position of inline-level absolute-positioned elements, with combinations of float, direction, and text-align." />
5+
<style>
6+
#container { position: relative; background: red; width: 100px; height: 100px; }
7+
#container > div { background: green; }
8+
#inflow { height: 50px; }
9+
#float { float: left; width: 50px; height: 50px; }
10+
#abs { display: inline; position: absolute; width: 50px; height: 50px; }
11+
</style>
12+
<p>Test passes if there is a filled green square.</p>
13+
<div id=container style="direction: rtl; text-align: right;">
14+
<div id=inflow></div>
15+
<div id=float style="float: left;"></div>
16+
<div id=abs style="transform: translateX(0%);"></div>
17+
</div>

0 commit comments

Comments
 (0)