commit ff7d3e2bcaf5800d20b887aa0f1f6a1ed27d8a2f
parent a50088adb2eded22a03c6c60227df8716e8770eb
Author: David Shin <dshin@mozilla.com>
Date: Sat, 13 Dec 2025 01:34:50 +0000
Bug 2005756: Only clear computed margin on anchor-center of a side specifying auto. r=layout-anchor-positioning-reviewers,layout-reviewers,emilio
Differential Revision: https://phabricator.services.mozilla.com/D276265
Diffstat:
6 files changed, 312 insertions(+), 13 deletions(-)
diff --git a/layout/generic/AbsoluteContainingBlock.cpp b/layout/generic/AbsoluteContainingBlock.cpp
@@ -977,7 +977,7 @@ void AbsoluteContainingBlock::ResolveAutoMarginsAfterLayout(
const auto anchorResolutionParams =
AnchorPosResolutionParams::From(&aKidReflowInput);
- auto ResolveMarginsInAxis = [&](LogicalAxis aAxis) {
+ auto ResolveMarginsInAxis = [&](LogicalAxis aAxis, bool aAnchorCenter) {
const auto startSide = MakeLogicalSide(aAxis, LogicalEdge::Start);
const auto endSide = MakeLogicalSide(aAxis, LogicalEdge::End);
@@ -1006,18 +1006,20 @@ void AbsoluteContainingBlock::ResolveAutoMarginsAfterLayout(
->IsAuto();
if (aAxis == LogicalAxis::Inline) {
- ReflowInput::ComputeAbsPosInlineAutoMargin(availMarginSpace, outerWM,
- startSideMarginIsAuto,
- endSideMarginIsAuto, aMargin);
+ ReflowInput::ComputeAbsPosInlineAutoMargin(
+ availMarginSpace, outerWM, startSideMarginIsAuto, endSideMarginIsAuto,
+ aAnchorCenter, aMargin);
} else {
- ReflowInput::ComputeAbsPosBlockAutoMargin(availMarginSpace, outerWM,
- startSideMarginIsAuto,
- endSideMarginIsAuto, aMargin);
+ ReflowInput::ComputeAbsPosBlockAutoMargin(
+ availMarginSpace, outerWM, startSideMarginIsAuto, endSideMarginIsAuto,
+ aAnchorCenter, aMargin);
}
};
- ResolveMarginsInAxis(LogicalAxis::Inline);
- ResolveMarginsInAxis(LogicalAxis::Block);
+ ResolveMarginsInAxis(LogicalAxis::Inline,
+ aKidReflowInput.mFlags.mIAnchorCenter);
+ ResolveMarginsInAxis(LogicalAxis::Block,
+ aKidReflowInput.mFlags.mBAnchorCenter);
aKidReflowInput.SetComputedLogicalMargin(outerWM, aMargin);
nsMargin* propValue =
@@ -1415,12 +1417,10 @@ void AbsoluteContainingBlock::ReflowAbsoluteFrame(
// margin for us in that axis (since the thing that's aligned is the
// margin box). So, we clear out the margin here to avoid applying it
// twice.
- if (kidReflowInput.mFlags.mIOffsetsNeedCSSAlign ||
- kidReflowInput.mFlags.mIAnchorCenter) {
+ if (kidReflowInput.mFlags.mIOffsetsNeedCSSAlign) {
margin.IStart(outerWM) = margin.IEnd(outerWM) = 0;
}
- if (kidReflowInput.mFlags.mBOffsetsNeedCSSAlign ||
- kidReflowInput.mFlags.mBAnchorCenter) {
+ if (kidReflowInput.mFlags.mBOffsetsNeedCSSAlign) {
margin.BStart(outerWM) = margin.BEnd(outerWM) = 0;
}
diff --git a/layout/generic/ReflowInput.cpp b/layout/generic/ReflowInput.cpp
@@ -1188,7 +1188,18 @@ void ReflowInput::ComputeAbsPosInlineAutoMargin(nscoord aAvailMarginSpace,
WritingMode aContainingBlockWM,
bool aIsMarginIStartAuto,
bool aIsMarginIEndAuto,
+ bool aIsIAnchorCenter,
LogicalMargin& aMargin) {
+ if (aIsIAnchorCenter) {
+ // `anchor-center` sets any use of `auto` margin to 0.
+ if (aIsMarginIStartAuto) {
+ aMargin.IStart(aContainingBlockWM) = 0;
+ }
+ if (aIsMarginIEndAuto) {
+ aMargin.IEnd(aContainingBlockWM) = 0;
+ }
+ return;
+ }
if (aIsMarginIStartAuto) {
if (aIsMarginIEndAuto) {
if (aAvailMarginSpace < 0) {
@@ -1222,7 +1233,18 @@ void ReflowInput::ComputeAbsPosBlockAutoMargin(nscoord aAvailMarginSpace,
WritingMode aContainingBlockWM,
bool aIsMarginBStartAuto,
bool aIsMarginBEndAuto,
+ bool aIsBAnchorCenter,
LogicalMargin& aMargin) {
+ if (aIsBAnchorCenter) {
+ // `anchor-center` sets any use of `auto` margin to 0.
+ if (aIsMarginBStartAuto) {
+ aMargin.BStart(aContainingBlockWM) = 0;
+ }
+ if (aIsMarginBEndAuto) {
+ aMargin.BEnd(aContainingBlockWM) = 0;
+ }
+ return;
+ }
if (aIsMarginBStartAuto) {
if (aIsMarginBEndAuto) {
// Both 'margin-top' and 'margin-bottom' are 'auto', so they get
diff --git a/layout/generic/ReflowInput.h b/layout/generic/ReflowInput.h
@@ -824,6 +824,7 @@ struct ReflowInput : public SizeComputationInput {
WritingMode aContainingBlockWM,
bool aIsMarginBStartAuto,
bool aIsMarginBEndAuto,
+ bool aIsIAnchorCenter,
LogicalMargin& aMargin);
// Resolve any inline-axis 'auto' margins (if any) for an absolutely
@@ -833,6 +834,7 @@ struct ReflowInput : public SizeComputationInput {
WritingMode aContainingBlockWM,
bool aIsMarginIStartAuto,
bool aIsMarginIEndAuto,
+ bool aIsBAnchorCenter,
LogicalMargin& aMargin);
protected:
diff --git a/testing/web-platform/tests/css/css-anchor-position/anchor-center-004.html b/testing/web-platform/tests/css/css-anchor-position/anchor-center-004.html
@@ -0,0 +1,56 @@
+<!DOCTYPE html>
+<link rel="help" href="https://drafts.csswg.org/css-anchor-position-1/#anchor-center">
+<link rel="author" href="mailto:dshin@mozilla.com">
+<title>Tests the position of 'anchor-center' alignment with target margin: auto.</title>
+<style>
+.container {
+ width: 100px;
+ height: 100px;
+ border: solid 3px;
+ position: relative;
+ margin: 50px;
+}
+
+.anchor {
+ anchor-name: --anchor;
+ position: relative;
+ width: 50px;
+ height: 50px;
+ left: 30px;
+ top: 20px;
+ background: lime;
+}
+
+.target {
+ position-anchor: --anchor;
+ width: 24px;
+ height: 24px;
+ position: fixed;
+ background: cyan;
+}
+
+.justify {
+ justify-self: anchor-center;
+ top: anchor(bottom);
+ /* Should be overridden to 0. */
+ margin-inline: auto;
+}
+
+.align {
+ align-self: anchor-center;
+ right: anchor(left);
+ /* Should be overridden to 0. */
+ margin-block: auto;
+}
+</style>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/resources/check-layout-th.js"></script>
+
+<body onload="checkLayout('.target')">
+
+<div class="container">
+ <div class="anchor"></div>
+ <div class="target justify" data-offset-x="104"></div>
+ <div class="target align" data-offset-y="86"></div>
+</div>
diff --git a/testing/web-platform/tests/css/css-anchor-position/anchor-center-overflow-005-ref.html b/testing/web-platform/tests/css/css-anchor-position/anchor-center-overflow-005-ref.html
@@ -0,0 +1,112 @@
+<!DOCTYPE html>
+<title>anchor-center overflow adjustments (anchored < inset area, with margin)</title>
+<style>
+.abs-cb {
+ display: inline-block;
+ box-sizing: border-box;
+ border: 5px solid;
+ width: 100px;
+ height: 100px;
+ position: relative;
+}
+
+.anchor {
+ width: 20px;
+ height: 20px;
+ background: pink;
+ position: absolute;
+ inset: 0;
+}
+
+.positioned {
+ position: absolute;
+ width: 50px;
+ height: 50px;
+ margin: 5px;
+ background: purple;
+}
+
+.anchor.tl {
+ align-self: start;
+ justify-self: start;
+}
+
+.anchor.tr {
+ align-self: start;
+ justify-self: end;
+}
+
+.anchor.bl {
+ align-self: end;
+ justify-self: start;
+}
+
+.anchor.br {
+ align-self: end;
+ justify-self: end;
+}
+
+.positioned.bl {
+ left: 0;
+ top: 20px;
+}
+
+.positioned.lr {
+ left: 20px;
+ top: 0;
+}
+
+
+.positioned.bc {
+ top: anchor(bottom);
+ justify-self: anchor-center;
+}
+
+.positioned.tc {
+ bottom: anchor(top);
+ justify-self: anchor-center;
+}
+
+.positioned.cr {
+ left: anchor(right);
+ align-self: anchor-center;
+}
+
+.positioned.cl {
+ right: anchor(left);
+ align-self: anchor-center;
+}
+</style>
+</style>
+<div class=abs-cb>
+ <div class="anchor tl"></div>
+ <div class=positioned style="left: 0; top: 20px;"></div>
+</div
+><div class=abs-cb>
+ <div class="anchor tl"></div>
+ <div class=positioned style="left: 20px; top: 0;"></div>
+</div
+><div class=abs-cb>
+ <div class="anchor tr"></div>
+ <div class=positioned style="right: 0; top: 20px;"></div>
+</div
+><div class=abs-cb>
+ <div class="anchor tr"></div>
+ <div class=positioned style="right: 20px; top: 0px;"></div>
+</div><br>
+<div class=abs-cb>
+ <div class="anchor bl"></div>
+ <div class=positioned style="bottom: 20px; left: 0;"></div>
+</div
+><div class=abs-cb>
+ <div class="anchor bl"></div>
+ <div class=positioned style="bottom: 0; left: 20px;"></div>
+</div
+><div class=abs-cb>
+ <div class="anchor br"></div>
+ <div class=positioned style="bottom: 20px; right: 0;"></div>
+</div
+><div class=abs-cb>
+ <div class="anchor br"></div>
+ <div class=positioned style="bottom: 0; right: 20px;"></div>
+</div>
diff --git a/testing/web-platform/tests/css/css-anchor-position/anchor-center-overflow-005.html b/testing/web-platform/tests/css/css-anchor-position/anchor-center-overflow-005.html
@@ -0,0 +1,106 @@
+<!DOCTYPE html>
+<title>anchor-center overflow adjustments (anchored < inset area, with margin)</title>
+<link rel="help" href="https://www.w3.org/TR/css-anchor-position-1/#anchor-center">
+<link rel="match" href="anchor-center-overflow-005-ref.html">
+<link rel="author" name="David Shin" href="mailto:dshin@mozilla.com">
+<style>
+.abs-cb {
+ display: inline-block;
+ box-sizing: border-box;
+ border: 5px solid;
+ width: 100px;
+ height: 100px;
+ anchor-scope: --a;
+ position: relative;
+}
+
+.anchor {
+ anchor-name: --a;
+ width: 20px;
+ height: 20px;
+ background: pink;
+ position: absolute;
+ inset: 0;
+}
+
+.positioned {
+ position: absolute;
+ width: 50px;
+ height: 50px;
+ margin: 5px;
+ position-anchor: --a;
+ background: purple;
+}
+
+.anchor.tl {
+ align-self: start;
+ justify-self: start;
+}
+
+.anchor.tr {
+ align-self: start;
+ justify-self: end;
+}
+
+.anchor.bl {
+ align-self: end;
+ justify-self: start;
+}
+
+.anchor.br {
+ align-self: end;
+ justify-self: end;
+}
+
+.positioned.bc {
+ top: anchor(bottom);
+ justify-self: anchor-center;
+}
+
+.positioned.tc {
+ bottom: anchor(top);
+ justify-self: anchor-center;
+}
+
+.positioned.cr {
+ left: anchor(right);
+ align-self: anchor-center;
+}
+
+.positioned.cl {
+ right: anchor(left);
+ align-self: anchor-center;
+}
+</style>
+<div class=abs-cb>
+ <div class="anchor tl"></div>
+ <div class="positioned bc"></div>
+</div
+><div class=abs-cb>
+ <div class="anchor tl"></div>
+ <div class="positioned cr"></div>
+</div
+><div class=abs-cb>
+ <div class="anchor tr"></div>
+ <div class="positioned bc"></div>
+</div
+><div class=abs-cb>
+ <div class="anchor tr"></div>
+ <div class="positioned cl"></div>
+</div><br>
+<div class=abs-cb>
+ <div class="anchor bl"></div>
+ <div class="positioned tc"></div>
+</div
+><div class=abs-cb>
+ <div class="anchor bl"></div>
+ <div class="positioned cr"></div>
+</div
+><div class=abs-cb>
+ <div class="anchor br"></div>
+ <div class="positioned tc"></div>
+</div
+><div class=abs-cb>
+ <div class="anchor br"></div>
+ <div class="positioned cl"></div>
+</div>
+\ No newline at end of file