1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-23 19:07:34 +00:00

LibWeb: Honor negative margins on atomic inlines

Sizing already worked correctly, but before this change, we were too
aggressive with inserting line breaks when negative margins would
still an atomic inline to fit on the line.
This commit is contained in:
Andreas Kling 2023-12-10 10:09:38 +01:00
parent 3ae29fdeec
commit 7abb182fa3
5 changed files with 80 additions and 1 deletions

View file

@ -0,0 +1,14 @@
Viewport <#document> at (0,0) content-size 800x600 children: not-inline
BlockContainer <html> at (0,0) content-size 800x60 [BFC] children: not-inline
BlockContainer <body> at (5,5) content-size 150x50 children: inline
line 0 width: 150, height: 50, bottom: 50, baseline: 50
frag 0 from BlockContainer start: 0, length: 0, rect: [5,5 100x50]
frag 1 from BlockContainer start: 0, length: 0, rect: [55,5 100x50]
BlockContainer <div.foo> at (5,5) content-size 100x50 inline-block [BFC] children: not-inline
BlockContainer <div.bar> at (55,5) content-size 100x50 inline-block [BFC] children: not-inline
ViewportPaintable (Viewport<#document>) [0,0 800x600]
PaintableWithLines (BlockContainer<HTML>) [0,0 800x60]
PaintableWithLines (BlockContainer<BODY>) [0,0 160x60]
PaintableWithLines (BlockContainer<DIV>.foo) [5,5 100x50]
PaintableWithLines (BlockContainer<DIV>.bar) [55,5 100x50]

View file

@ -0,0 +1,14 @@
Viewport <#document> at (0,0) content-size 800x600 children: not-inline
BlockContainer <html> at (0,0) content-size 800x60 [BFC] children: not-inline
BlockContainer <body> at (5,5) content-size 150x50 children: inline
line 0 width: 150, height: 50, bottom: 50, baseline: 50
frag 0 from BlockContainer start: 0, length: 0, rect: [5,5 100x50]
frag 1 from BlockContainer start: 0, length: 0, rect: [105,5 100x50]
BlockContainer <div.foo> at (5,5) content-size 100x50 inline-block [BFC] children: not-inline
BlockContainer <div.bar> at (105,5) content-size 100x50 inline-block [BFC] children: not-inline
ViewportPaintable (Viewport<#document>) [0,0 800x600]
PaintableWithLines (BlockContainer<HTML>) [0,0 800x60]
PaintableWithLines (BlockContainer<BODY>) [0,0 160x60] overflow: [5,5 200x50]
PaintableWithLines (BlockContainer<DIV>.foo) [5,5 100x50]
PaintableWithLines (BlockContainer<DIV>.bar) [105,5 100x50]

View file

@ -0,0 +1,23 @@
<!doctype html><style>
* {
margin: 0;
padding: 0;
}
body {
width: max-content;
border: 5px solid black;
}
.foo {
display: inline-block;
background: orange;
width: 100px;
height: 50px;
}
.bar {
display: inline-block;
background: magenta;
margin-left: -50px;
width: 100px;
height: 50px;
}
</style><body><div class="foo"></div><div class="bar"></div>

View file

@ -0,0 +1,23 @@
<!doctype html><style>
* {
margin: 0;
padding: 0;
}
body {
width: max-content;
border: 5px solid black;
}
.foo {
display: inline-block;
background: orange;
width: 100px;
height: 50px;
}
.bar {
display: inline-block;
background: magenta;
margin-right: -50px;
width: 100px;
height: 50px;
}
</style><body><div class="foo"></div><div class="bar"></div>

View file

@ -275,7 +275,12 @@ void InlineFormattingContext::generate_line_boxes(LayoutMode layout_mode)
auto& box = verify_cast<Layout::Box>(*item.node);
compute_inset(box);
if (containing_block().computed_values().white_space() != CSS::WhiteSpace::Nowrap) {
line_builder.break_if_needed(item.border_box_width());
auto minimum_space_needed_on_line = item.border_box_width();
if (item.margin_start < 0)
minimum_space_needed_on_line += item.margin_start;
if (item.margin_end < 0)
minimum_space_needed_on_line += item.margin_end;
line_builder.break_if_needed(minimum_space_needed_on_line);
}
line_builder.append_box(box, item.border_start + item.padding_start, item.padding_end + item.border_end, item.margin_start, item.margin_end);
break;