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

Reply via email to