Bug 807897: Make non-auto values for "z-index" turn flex items into stacking contexts, even if they're not positioned. r=dbaron

This commit is contained in:
Daniel Holbert
2012-11-20 17:24:59 -08:00
parent 46d6eeca43
commit 87a04479ef
5 changed files with 247 additions and 2 deletions

View File

@@ -1906,7 +1906,7 @@ nsLayoutUtils::PaintFrame(nsRenderingContext* aRenderingContext, nsIFrame* aFram
int32_t
nsLayoutUtils::GetZIndex(nsIFrame* aFrame) {
if (!aFrame->IsPositioned())
if (!aFrame->IsPositioned() && !aFrame->IsFlexItem())
return 0;
const nsStylePosition* position =

View File

@@ -954,6 +954,24 @@ nsFlexContainerFrame::GetFrameName(nsAString& aResult) const
}
#endif // DEBUG
// Helper for BuildDisplayList, to implement this special-case for flex items
// from the spec:
// Flex items paint exactly the same as block-level elements in the
// normal flow, except that 'z-index' values other than 'auto' create
// a stacking context even if 'position' is 'static'.
// http://www.w3.org/TR/2012/CR-css3-flexbox-20120918/#painting
uint32_t
GetDisplayFlagsForFlexItem(nsIFrame* aFrame)
{
MOZ_ASSERT(aFrame->IsFlexItem(), "Should only be called on flex items");
const nsStylePosition* pos = aFrame->GetStylePosition();
if (pos->mZIndex.GetUnit() == eStyleUnit_Integer) {
return nsIFrame::DISPLAY_CHILD_FORCE_STACKING_CONTEXT;
}
return 0;
}
NS_IMETHODIMP
nsFlexContainerFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
const nsRect& aDirtyRect,
@@ -963,7 +981,8 @@ nsFlexContainerFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
NS_ENSURE_SUCCESS(rv, rv);
for (nsFrameList::Enumerator e(mFrames); !e.AtEnd(); e.Next()) {
rv = BuildDisplayListForChild(aBuilder, e.get(), aDirtyRect, aLists);
rv = BuildDisplayListForChild(aBuilder, e.get(), aDirtyRect, aLists,
GetDisplayFlagsForFlexItem(e.get()));
NS_ENSURE_SUCCESS(rv, rv);
}

View File

@@ -0,0 +1,113 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<!-- Reference case, with floated elements in place of flex items, and using
"position: relative" on those elements, to make z-index work on them
outside of a flex container. -->
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<style>
.flexbox {
width: -moz-max-content;
height: 10px;
border: 2px solid gray;
margin-bottom: 10px;
}
.a {
width: 10px;
height: 10px;
background: lightblue;
min-width: 0;
float: left;
}
.b {
width: 10px;
height: 10px;
background: pink;
min-width: 0;
margin-right: 10px;
float: left;
}
.aKid {
margin-left: 3px;
margin-top: 3px;
width: 10px;
height: 10px;
background: steelblue;
border: 1px solid blue;
}
.bKid {
margin-left: 3px;
margin-top: 6px;
width: 10px;
height: 10px;
background: violet;
border: 1px solid purple;
}
.z0, .z1, .zn1 { position: relative; }
.z0 { z-index: 0; }
.z1 { z-index: 1; }
.zn1 { z-index: -1; }
</style>
</head>
<body>
<!-- No "z-index" -->
<div class="flexbox">
<div class="a"><div class="aKid"/></div>
<div class="b"><div class="bKid"/></div>
</div>
<!-- Various "z-index" just on the first item -->
<div class="flexbox">
<div class="a zn1"><div class="aKid"/></div>
<div class="b"><div class="bKid"/></div>
<div class="a z0"><div class="aKid"/></div>
<div class="b"><div class="bKid"/></div>
<div class="a z1"><div class="aKid"/></div>
<div class="b"><div class="bKid"/></div>
</div>
<!-- Various "z-index" just on the second item -->
<div class="flexbox">
<div class="a"><div class="aKid"/></div>
<div class="b zn1"><div class="bKid"/></div>
<div class="a"><div class="aKid"/></div>
<div class="b z0"><div class="bKid"/></div>
<div class="a"><div class="aKid"/></div>
<div class="b z1"><div class="bKid"/></div>
</div>
<!-- Various "z-index" on the first item, w/ "z-index:0" on second item -->
<div class="flexbox">
<div class="a zn1"><div class="aKid"/></div>
<div class="b z0"><div class="bKid"/></div>
<div class="a z0"><div class="aKid"/></div>
<div class="b z0"><div class="bKid"/></div>
<div class="a z1"><div class="aKid"/></div>
<div class="b z0"><div class="bKid"/></div>
</div>
<!-- Various "z-index" on the second item, w/ "z-index:0" on first item -->
<div class="flexbox">
<div class="a z0"><div class="aKid"/></div>
<div class="b zn1"><div class="bKid"/></div>
<div class="a z0"><div class="aKid"/></div>
<div class="b z0"><div class="bKid"/></div>
<div class="a z0"><div class="aKid"/></div>
<div class="b z1"><div class="bKid"/></div>
</div>
</body>
</html>

View File

@@ -0,0 +1,110 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<!-- Testcase with flex items containing overlapping content, with
"z-index" set on some of them, which should make them create
stacking contexts. -->
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<style>
.flexbox {
width: -moz-max-content;
height: 10px;
border: 2px solid gray;
display: flex;
margin-bottom: 10px;
}
.a {
width: 10px;
height: 10px;
background: lightblue;
min-width: 0;
}
.b {
width: 10px;
height: 10px;
background: pink;
min-width: 0;
margin-right: 10px;
}
.aKid {
margin-left: 3px;
margin-top: 3px;
width: 10px;
height: 10px;
background: steelblue;
border: 1px solid blue;
}
.bKid {
margin-left: 3px;
margin-top: 6px;
width: 10px;
height: 10px;
background: violet;
border: 1px solid purple;
}
.z0 { z-index: 0; }
.z1 { z-index: 1; }
.zn1 { z-index: -1; }
</style>
</head>
<body>
<!-- No "z-index" -->
<div class="flexbox">
<div class="a"><div class="aKid"/></div>
<div class="b"><div class="bKid"/></div>
</div>
<!-- Various "z-index" just on the first item -->
<div class="flexbox">
<div class="a zn1"><div class="aKid"/></div>
<div class="b"><div class="bKid"/></div>
<div class="a z0"><div class="aKid"/></div>
<div class="b"><div class="bKid"/></div>
<div class="a z1"><div class="aKid"/></div>
<div class="b"><div class="bKid"/></div>
</div>
<!-- Various "z-index" just on the second item -->
<div class="flexbox">
<div class="a"><div class="aKid"/></div>
<div class="b zn1"><div class="bKid"/></div>
<div class="a"><div class="aKid"/></div>
<div class="b z0"><div class="bKid"/></div>
<div class="a"><div class="aKid"/></div>
<div class="b z1"><div class="bKid"/></div>
</div>
<!-- Various "z-index" on the first item, w/ "z-index:0" on second item -->
<div class="flexbox">
<div class="a zn1"><div class="aKid"/></div>
<div class="b z0"><div class="bKid"/></div>
<div class="a z0"><div class="aKid"/></div>
<div class="b z0"><div class="bKid"/></div>
<div class="a z1"><div class="aKid"/></div>
<div class="b z0"><div class="bKid"/></div>
</div>
<!-- Various "z-index" on the second item, w/ "z-index:0" on first item -->
<div class="flexbox">
<div class="a z0"><div class="aKid"/></div>
<div class="b zn1"><div class="bKid"/></div>
<div class="a z0"><div class="aKid"/></div>
<div class="b z0"><div class="bKid"/></div>
<div class="a z0"><div class="aKid"/></div>
<div class="b z1"><div class="bKid"/></div>
</div>
</body>
</html>

View File

@@ -93,6 +93,9 @@ pref(layout.css.flexbox.enabled,true) == flexbox-float-1d.xhtml flexbox-float-1
test-pref(layout.css.flexbox.enabled,true) == flexbox-float-2a.xhtml flexbox-float-2-ref.xhtml
test-pref(layout.css.flexbox.enabled,true) == flexbox-float-2b.xhtml flexbox-float-2-ref.xhtml
# Tests for flex items as stacking contexts
test-pref(layout.css.flexbox.enabled,true) == flexbox-items-as-stacking-contexts-1.xhtml flexbox-items-as-stacking-contexts-1-ref.xhtml
# Tests for (default) "min-width: auto" / "min-height: auto" in flex containers
test-pref(layout.css.flexbox.enabled,true) == flexbox-minSize-horiz-1.xhtml flexbox-minSize-horiz-1-ref.xhtml
test-pref(layout.css.flexbox.enabled,true) == flexbox-minSize-vert-1.xhtml flexbox-minSize-vert-1-ref.xhtml