From 8d41f2e6741b11b0cfb6b77c4343e37f8b7e9464 Mon Sep 17 00:00:00 2001 From: Ting-Yu Lin Date: Thu, 25 Apr 2024 23:32:47 +0000 Subject: [PATCH] Bug 1748891 Part 3 - Exclude flex item's margin-box at sticky position in flex container's scrollable overflow area. r=emilio Differential Revision: https://phabricator.services.mozilla.com/D208173 --- layout/generic/nsFlexContainerFrame.cpp | 21 +++++++--- .../sticky/position-sticky-left-006.html | 38 +++++++++++++++++++ .../sticky/position-sticky-top-006.html | 38 +++++++++++++++++++ 3 files changed, 92 insertions(+), 5 deletions(-) create mode 100644 testing/web-platform/tests/css/css-position/sticky/position-sticky-left-006.html create mode 100644 testing/web-platform/tests/css/css-position/sticky/position-sticky-top-006.html diff --git a/layout/generic/nsFlexContainerFrame.cpp b/layout/generic/nsFlexContainerFrame.cpp index 40fb216328f7..d76d698be82c 100644 --- a/layout/generic/nsFlexContainerFrame.cpp +++ b/layout/generic/nsFlexContainerFrame.cpp @@ -4886,8 +4886,14 @@ void nsFlexContainerFrame::UnionInFlowChildOverflow( bool anyScrolledContentItem = false; // Union of normal-positioned margin boxes for all the items. nsRect itemMarginBoxes; - // Union of relative-positioned margin boxes for the relpos items only. - nsRect relPosItemMarginBoxes; + // Overflow areas containing the union of relative-positioned and + // stick-positioned margin boxes of relpos items. + // + // Note for sticky-positioned margin boxes, we only union it with the ink + // overflow to avoid circular dependencies with the scroll container. (The + // scroll position and the scroll container's size impact the sticky position, + // so we don't want the sticky position to impact them.) + OverflowAreas relPosItemMarginBoxes; const bool useMozBoxCollapseBehavior = StyleVisibility()->UseLegacyCollapseBehavior(); for (nsIFrame* f : mFrames) { @@ -4906,8 +4912,13 @@ void nsFlexContainerFrame::UnionInFlowChildOverflow( const nsRect marginRect = f->GetMarginRectRelativeToSelf(); itemMarginBoxes = itemMarginBoxes.Union(marginRect + f->GetNormalPosition()); - relPosItemMarginBoxes = - relPosItemMarginBoxes.Union(marginRect + f->GetPosition()); + if (f->IsRelativelyPositioned()) { + relPosItemMarginBoxes.UnionAllWith(marginRect + f->GetPosition()); + } else { + MOZ_ASSERT(f->IsStickyPositioned()); + relPosItemMarginBoxes.UnionWith( + OverflowAreas(marginRect + f->GetPosition(), nsRect())); + } } else { itemMarginBoxes = itemMarginBoxes.Union(f->GetMarginRect()); } @@ -4916,7 +4927,7 @@ void nsFlexContainerFrame::UnionInFlowChildOverflow( if (anyScrolledContentItem) { itemMarginBoxes.Inflate(GetUsedPadding()); aOverflowAreas.UnionAllWith(itemMarginBoxes); - aOverflowAreas.UnionAllWith(relPosItemMarginBoxes); + aOverflowAreas.UnionWith(relPosItemMarginBoxes); } } diff --git a/testing/web-platform/tests/css/css-position/sticky/position-sticky-left-006.html b/testing/web-platform/tests/css/css-position/sticky/position-sticky-left-006.html new file mode 100644 index 000000000000..63fa1ebfd89c --- /dev/null +++ b/testing/web-platform/tests/css/css-position/sticky/position-sticky-left-006.html @@ -0,0 +1,38 @@ + + +CSS Position Test: Test position:sticky element with 100% left in a flex container + + + + + + + + + + +

Test passes if there is a filled green square and no red.

+
+
+
+ + diff --git a/testing/web-platform/tests/css/css-position/sticky/position-sticky-top-006.html b/testing/web-platform/tests/css/css-position/sticky/position-sticky-top-006.html new file mode 100644 index 000000000000..4ac5310bf356 --- /dev/null +++ b/testing/web-platform/tests/css/css-position/sticky/position-sticky-top-006.html @@ -0,0 +1,38 @@ + + +CSS Position Test: Test position:sticky element with 100% top in a flex container + + + + + + + + + + +

Test passes if there is a filled green square and no red.

+
+
+
+ +