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
This commit is contained in:
Ting-Yu Lin 2024-04-25 23:32:47 +00:00
parent 955961b1da
commit 8d41f2e674
3 changed files with 92 additions and 5 deletions

View File

@ -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);
}
}

View File

@ -0,0 +1,38 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>CSS Position Test: Test position:sticky element with 100% left in a flex container</title>
<link rel="author" title="Ting-Yu Lin" href="mailto:tlin@mozilla.com">
<link rel="author" title="Mozilla" href="https://www.mozilla.org/">
<link rel="help" href="https://drafts.csswg.org/css-position/#sticky-pos">
<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1748891">
<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1835705">
<link rel="match" href="../../reference/ref-filled-green-100px-square.xht">
<meta name="assert" content="This test verifies that a position:sticky element with 100% left value does not cause the scrollbar to show when shrinking the width of its overflow container.">
<style>
#scroll {
display: flex;
width: 200px;
height: 100px;
overflow: auto;
background: red;
}
.sticky {
position: sticky;
width: 100px;
height: 100px;
left: 100%;
background: green;
}
</style>
<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
<div id="scroll">
<div class="sticky"></div>
</div>
<script>
window.onload = () => {
document.getElementById("scroll").style.width = "100px";
};
</script>

View File

@ -0,0 +1,38 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>CSS Position Test: Test position:sticky element with 100% top in a flex container</title>
<link rel="author" title="Ting-Yu Lin" href="mailto:tlin@mozilla.com">
<link rel="author" title="Mozilla" href="https://www.mozilla.org/">
<link rel="help" href="https://drafts.csswg.org/css-position/#sticky-pos">
<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1748891">
<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1835705">
<link rel="match" href="../../reference/ref-filled-green-100px-square.xht">
<meta name="assert" content="This test verifies that a position:sticky element with 100% top value does not cause the scrollbar to show when shrinking the height of its container.">
<style>
#scroll {
display: flex;
width: 100px;
height: 200px;
overflow: auto;
background: red;
}
.sticky {
position: sticky;
width: 100px;
height: 100px;
top: 100%;
background: green;
}
</style>
<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
<div id="scroll">
<div class="sticky"></div>
</div>
<script>
window.onload = () => {
document.getElementById("scroll").style.height = "100px";
};
</script>