Handle the special case of a flex frame being the absolute containing block correctly from the CSS align code

This commit is contained in:
Fedor 2019-05-20 09:01:07 +03:00
parent 88427f4eeb
commit 2f95386dbb
6 changed files with 148 additions and 6 deletions

View File

@ -409,14 +409,30 @@ OffsetToAlignedStaticPos(const ReflowInput& aKidReflowInput,
? GetOrthogonalAxis(aAbsPosCBAxis)
: aAbsPosCBAxis);
const bool placeholderContainerIsContainingBlock =
aPlaceholderContainer == aKidReflowInput.mCBReflowInput->mFrame;
nsIAtom* parentType = aPlaceholderContainer->GetType();
LogicalSize alignAreaSize(pcWM);
if (parentType == nsGkAtoms::flexContainerFrame) {
// 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 == nsGkAtoms::gridContainerFrame) {
// 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
@ -424,7 +440,7 @@ OffsetToAlignedStaticPos(const ReflowInput& aKidReflowInput,
// 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);

View File

@ -0,0 +1,27 @@
<!DOCTYPE html>
<html><head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8"><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>
</head><body><div class="parent"><div class="child"></div></div>
</body></html>

View File

@ -0,0 +1,30 @@
<!DOCTYPE html>
<html><head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8"><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="https://hg.mozilla.org/mozilla-central/raw-file/6538de3b6137/layout/reftests/w3c-css/submitted/flexbox/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>
</head><body><div class="parent"><div class="child"></div></div>
</body></html>

View File

@ -0,0 +1,27 @@
<!DOCTYPE html>
<html><head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8"><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>
</head><body><div class="parent"><div class="child"></div></div>
</body></html>

View File

@ -0,0 +1,38 @@
<!DOCTYPE html>
<html><head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8"><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="https://hg.mozilla.org/mozilla-central/raw-file/6538de3b6137/layout/reftests/w3c-css/submitted/flexbox/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>
</head><body><div class="parent"><div class="child"></div></div>
</body></html>

View File

@ -211,3 +211,7 @@ fails == flexbox-min-height-auto-002b.html flexbox-min-height-auto-002-ref.html
== 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