Bug 1386654: Handle the special case of a flex frame being the absolute containing block correctly from the CSS align code. r=dholbert
authorEmilio Cobos Álvarez <emilio@crisal.io>
Tue, 09 Jan 2018 23:50:47 +0100
changeset 452800 6538de3b61376dcdce3dcbcb620901edcfbab895
parent 452799 a20954ce2d02d0c7da1eeb4885b34ef4360fa2d4
child 452801 6ed39e3766f213317d4fd7cced1f07f2d793e10f
push id1648
push usermtabara@mozilla.com
push dateThu, 01 Mar 2018 12:45:47 +0000
treeherdermozilla-release@cbb9688c2eeb [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdholbert
bugs1386654
milestone59.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1386654: Handle the special case of a flex frame being the absolute containing block correctly from the CSS align code. r=dholbert MozReview-Commit-ID: 4fJtyX55Ig9
layout/generic/nsAbsoluteContainingBlock.cpp
layout/reftests/w3c-css/submitted/flexbox/position-absolute-containing-block-001-ref.html
layout/reftests/w3c-css/submitted/flexbox/position-absolute-containing-block-001.html
layout/reftests/w3c-css/submitted/flexbox/position-absolute-containing-block-002-ref.html
layout/reftests/w3c-css/submitted/flexbox/position-absolute-containing-block-002.html
layout/reftests/w3c-css/submitted/flexbox/reftest.list
--- a/layout/generic/nsAbsoluteContainingBlock.cpp
+++ b/layout/generic/nsAbsoluteContainingBlock.cpp
@@ -438,32 +438,48 @@ OffsetToAlignedStaticPos(const ReflowInp
   WritingMode pcWM = aPlaceholderContainer->GetWritingMode();
 
   // Find what axis aAbsPosCBAxis corresponds to, in placeholder's parent's
   // writing-mode.
   LogicalAxis pcAxis = (pcWM.IsOrthogonalTo(aAbsPosCBWM)
                         ? GetOrthogonalAxis(aAbsPosCBAxis)
                         : aAbsPosCBAxis);
 
+  const bool placeholderContainerIsContainingBlock =
+    aPlaceholderContainer == aKidReflowInput.mCBReflowInput->mFrame;
+
   LayoutFrameType parentType = aPlaceholderContainer->Type();
   LogicalSize alignAreaSize(pcWM);
   if (parentType == LayoutFrameType::FlexContainer) {
-    // The alignment container is the flex container's content box:
-    alignAreaSize = aPlaceholderContainer->GetLogicalSize(pcWM);
-    LogicalMargin pcBorderPadding =
-      aPlaceholderContainer->GetLogicalUsedBorderAndPadding(pcWM);
-    alignAreaSize -= pcBorderPadding.Size(pcWM);
+    // We store the frame rect in FinishAndStoreOverflow, which runs _after_
+    // reflowing the absolute frames, so handle the special case of the frame
+    // being the actual containing block here, by getting the size from
+    // aAbsPosCBSize.
+    //
+    // The alignment container is the flex container's content box.
+    if (placeholderContainerIsContainingBlock) {
+      alignAreaSize = aAbsPosCBSize.ConvertTo(pcWM, aAbsPosCBWM);
+      // aAbsPosCBSize is the padding-box, so substract the padding to get the
+      // content box.
+      alignAreaSize -=
+        aPlaceholderContainer->GetLogicalUsedPadding(pcWM).Size(pcWM);
+    } else {
+      alignAreaSize = aPlaceholderContainer->GetLogicalSize(pcWM);
+      LogicalMargin pcBorderPadding =
+        aPlaceholderContainer->GetLogicalUsedBorderAndPadding(pcWM);
+      alignAreaSize -= pcBorderPadding.Size(pcWM);
+    }
   } else if (parentType == LayoutFrameType::GridContainer) {
     // This abspos elem's parent is a grid container. Per CSS Grid 10.1 & 10.2:
     //  - If the grid container *also* generates the abspos containing block (a
     // grid area) for this abspos child, we use that abspos containing block as
     // the alignment container, too. (And its size is aAbsPosCBSize.)
     //  - Otherwise, we use the grid's padding box as the alignment container.
     // https://drafts.csswg.org/css-grid/#static-position
-    if (aPlaceholderContainer == aKidReflowInput.mCBReflowInput->mFrame) {
+    if (placeholderContainerIsContainingBlock) {
       // The alignment container is the grid area that we're using as the
       // absolute containing block.
       alignAreaSize = aAbsPosCBSize.ConvertTo(pcWM, aAbsPosCBWM);
     } else {
       // The alignment container is a the grid container's padding box (which
       // we can get by subtracting away its border from frame's size):
       alignAreaSize = aPlaceholderContainer->GetLogicalSize(pcWM);
       LogicalMargin pcBorder =
new file mode 100644
--- /dev/null
+++ b/layout/reftests/w3c-css/submitted/flexbox/position-absolute-containing-block-001-ref.html
@@ -0,0 +1,25 @@
+<!doctype html>
+<title>CSS Test Reference</title>
+<meta charset="utf-8">
+<link rel="author" title="Emilio Cobos Álvarez" href="mailto:emilio@crisal.io">
+<style>
+.parent {
+  position: fixed;
+  top: 0;
+  left: 0;
+  display: block;
+  width: 200px;
+  height: 200px;
+  background: yellow;
+}
+
+.child {
+  position: absolute;
+  left: 50px;
+  top: 50px;
+  width: 100px;
+  height: 100px;
+  background: green;
+}
+</style>
+<div class="parent"><div class="child"></div></div>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/w3c-css/submitted/flexbox/position-absolute-containing-block-001.html
@@ -0,0 +1,28 @@
+<!doctype html>
+<title>CSS Test: Absolutely positioned children of flex container with CSS align</title>
+<meta charset="utf-8">
+<link rel="help" href="https://drafts.csswg.org/css-flexbox/#abspos-items">
+<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1386654">
+<link rel="match" href="position-absolute-containing-block-001-ref.html">
+<link rel="author" title="Emilio Cobos Álvarez" href="mailto:emilio@crisal.io">
+<style>
+.parent {
+  position: fixed;
+  top: 0;
+  left: 0;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  width: 200px;
+  height: 200px;
+  background: yellow;
+}
+
+.child {
+  position: absolute;
+  width: 100px;
+  height: 100px;
+  background: green;
+}
+</style>
+<div class="parent"><div class="child"></div></div>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/w3c-css/submitted/flexbox/position-absolute-containing-block-002-ref.html
@@ -0,0 +1,25 @@
+<!doctype html>
+<title>CSS Test Reference</title>
+<meta charset="utf-8">
+<link rel="author" title="Emilio Cobos Álvarez" href="mailto:emilio@crisal.io">
+<style>
+.parent {
+  position: fixed;
+  top: 0;
+  left: 0;
+  display: block;
+  width: 200px;
+  height: 200px;
+  background: yellow;
+}
+
+.child {
+  position: absolute;
+  left: 60px;
+  top: 60px;
+  width: 100px;
+  height: 100px;
+  background: green;
+}
+</style>
+<div class="parent"><div class="child"></div></div>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/w3c-css/submitted/flexbox/position-absolute-containing-block-002.html
@@ -0,0 +1,36 @@
+<!doctype html>
+<title>CSS Test: Absolutely positioned children of flex container with CSS align</title>
+<meta charset="utf-8">
+<link rel="help" href="https://drafts.csswg.org/css-flexbox/#abspos-items">
+<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1386654">
+<link rel="match" href="position-absolute-containing-block-002-ref.html">
+<link rel="author" title="Emilio Cobos Álvarez" href="mailto:emilio@crisal.io">
+<style>
+.parent {
+  position: fixed;
+  top: 0;
+  left: 0;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  width: 180px;
+  height: 180px;
+
+  /* Expand the background area to 200px, without touching the content-box,
+     which is what flex absolute children should be aligned relative to. */
+  border-top: 5px solid yellow;
+  padding-top: 15px;
+  border-left: 5px solid yellow;
+  padding-left: 15px;
+
+  background: yellow;
+}
+
+.child {
+  position: absolute;
+  width: 100px;
+  height: 100px;
+  background: green;
+}
+</style>
+<div class="parent"><div class="child"></div></div>
--- a/layout/reftests/w3c-css/submitted/flexbox/reftest.list
+++ b/layout/reftests/w3c-css/submitted/flexbox/reftest.list
@@ -208,8 +208,12 @@ fails == flexbox-min-height-auto-002b.ht
 == flexbox-writing-mode-007.html flexbox-writing-mode-007-ref.html
 == flexbox-writing-mode-008.html flexbox-writing-mode-008-ref.html
 == flexbox-writing-mode-009.html flexbox-writing-mode-009-ref.html
 
 # Single-line size clamping
 == flexbox-single-line-clamp-1.html flexbox-single-line-clamp-1-ref.html
 == flexbox-single-line-clamp-2.html flexbox-single-line-clamp-2-ref.html
 == flexbox-single-line-clamp-3.html flexbox-single-line-clamp-3-ref.html
+
+# Flexbox as an absolute containing block.
+== position-absolute-containing-block-001.html position-absolute-containing-block-001-ref.html
+== position-absolute-containing-block-002.html position-absolute-containing-block-002-ref.html