Branch: refs/heads/main
Home: https://github.com/WebKit/WebKit
Commit: c2c6925c6d8b9b7a4c70700a779abf00dbac3a2c
https://github.com/WebKit/WebKit/commit/c2c6925c6d8b9b7a4c70700a779abf00dbac3a2c
Author: Alan Baradlay <[email protected]>
Date: 2025-12-04 (Thu, 04 Dec 2025)
Changed paths:
M Source/WebCore/layout/formattingContexts/block/BlockLayoutState.h
M
Source/WebCore/layout/formattingContexts/inline/InlineFormattingContext.cpp
M Source/WebCore/layout/formattingContexts/inline/InlineFormattingUtils.cpp
M Source/WebCore/layout/formattingContexts/inline/InlineFormattingUtils.h
M
Source/WebCore/layout/integration/LayoutIntegrationFormattingContextLayout.cpp
M Source/WebCore/layout/integration/LayoutIntegrationUtils.cpp
M Source/WebCore/layout/integration/LayoutIntegrationUtils.h
M Source/WebCore/layout/integration/inline/LayoutIntegrationLineLayout.cpp
M Source/WebCore/rendering/RenderBlockFlow.cpp
M Source/WebCore/rendering/RenderBlockFlow.h
Log Message:
-----------
[blocks-in-inline] Fix
fast/block/margin-collapse/block-inside-inline/011.html, 015.html and 016.html
https://bugs.webkit.org/show_bug.cgi?id=303517
Reviewed by Antti Koivisto.
This change adds support for self collapsing content, specifically this part of
margin collapsing:
"Otherwise, either the element's parent is not taking part in the margin
collapsing, or only the parent's bottom margin is involved. The position of the
element's top border edge is the same as it would have been if the element had
a non-zero bottom border."
https://www.w3.org/TR/CSS22/box.html#collapsing-margins
What it means is "content position bottom" and "next content top position" may
diverge.
Normally the current line's bottom position is where the next line starts.
However with self-collapsing block content, the next line's position may start
above the current line.
In practice the margin adjusted position for the next line still starts
adjacent to the current line (see example below) but
when the self-collapsing content is on the last line, the container may not
enclose it (that's one of the visual
effect of diverged positions).
Render tree implements this behavior by not expanding the logical height of the
container for such self-collapsing
blocks, but instead returns
1. the current height as the position for the next content
2. margin that needs to be propagated to "next content"
e.g.
<div class=container>
<span><div class=first style="margin-bottom: 150px">content</div></span>
<span><div class=second></div></span>
</div>
Calling RenderBlockFlow::layoutBlockChildFromInlineLayout on the [second] div
triggers this behavior.
1. At this point margin info has the bottom margin of 150px from the [first]
div.
2. [second] div is a self-collapsing block container (its top/bottom margins
are adjacent and they collapse with [first] div's bottom margin.
3. [second] div is positioned with the offset of 150px from the [first] div
(see spec above) but
the container's height is not expanded to enclose [second] div (essentially
no setLogicalHeight() call).
4. layoutBlockChildFromInlineLayout returns with
- the logical top for [second] div (that's where the second div is supposed
to go)
- the not-expanded logical height as the next content position (candidate
position for next line)
- margin info still has the 150px (as this margin is still "visible" to
whatever content comes next)
If there's no more content, this 150px margin gets propagated up on the
ancestor chain (next content) and we produce the following layout:
------------------- [container]
| --------------- [first]
| | content
| |_______________ ^
|___________________ | 150px
|
---------------- [second] v
(notice that the [second] div sticks out of its containing block)
However in case of some inflow content after the [second] div
<div class=container>
<span><div class=first style="margin-bottom: 150px">content</div></span>
<span><div class=second></div></span>
text after self collapsing box
</div>
the next line position is computed by
- taking the bottom of the [first] div (that's where the [container] ends
since we did not expand it)
- and offsetting it with the margin of 150px
producing the following layout:
------------------- [container]
| --------------- [first]
| | content
| |_______________ ^
| | 150px
| |
| ---------------- [second] v
| text after self....
--------------------
(So in practice the margin adjusted next line position is still after the
previous, self-collpaing line's bottom)
* Source/WebCore/layout/formattingContexts/block/BlockLayoutState.h:
(WebCore::Layout::BlockLayoutState::MarginState::resetMarginValues):
* Source/WebCore/layout/formattingContexts/inline/InlineFormattingContext.cpp:
(WebCore::Layout::InlineFormattingContext::lineLayout):
(WebCore::Layout::InlineFormattingContext::updateLayoutStateWithLineLayoutResult):
* Source/WebCore/layout/formattingContexts/inline/InlineFormattingUtils.cpp:
(WebCore::Layout::InlineFormattingUtils::logicalTopForNextLine const):
* Source/WebCore/layout/formattingContexts/inline/InlineFormattingUtils.h:
*
Source/WebCore/layout/integration/LayoutIntegrationFormattingContextLayout.cpp:
(WebCore::LayoutIntegration::layoutWithFormattingContextForBlockInInline):
* Source/WebCore/layout/integration/LayoutIntegrationUtils.cpp:
(WebCore::Layout::IntegrationUtils::toMarginState):
* Source/WebCore/layout/integration/LayoutIntegrationUtils.h:
* Source/WebCore/layout/integration/inline/LayoutIntegrationLineLayout.cpp:
(WebCore::LayoutIntegration::LineLayout::layout):
* Source/WebCore/rendering/RenderBlockFlow.cpp:
(WebCore::RenderBlockFlow::layoutBlockChildFromInlineLayout):
* Source/WebCore/rendering/RenderBlockFlow.h:
Canonical link: https://commits.webkit.org/303948@main
To unsubscribe from these emails, change your notification settings at
https://github.com/WebKit/WebKit/settings/notifications