Skip to content

Commit 721cb2a

Browse files
Composited negative z-index elements are hidden behind the body sometimes
https://bugs.webkit.org/show_bug.cgi?id=165080 rdar://problem/22260229 Reviewed by Zalan Bujtas. Source/WebCore: If the <body> falls into the "directly composited background color" code path (say, because it's composited because of composited negative z-index children, and has content of its own), then we failed to take root background propagation into account, and put the opaque root background color on the body's layer. Fix by sharing some code from RenderBox related to whether the body's renderer paints its background. Tests cover the buggy case, and the case where the <html> has its own background color. Tests: compositing/backgrounds/negative-z-index-behind-body-non-propagated.html compositing/backgrounds/negative-z-index-behind-body.html * rendering/RenderBox.cpp: (WebCore::RenderBox::paintsOwnBackground): (WebCore::RenderBox::paintBackground): (WebCore::RenderBox::backgroundIsKnownToBeOpaqueInRect): (WebCore::skipBodyBackground): Deleted. * rendering/RenderBox.h: * rendering/RenderLayerBacking.cpp: (WebCore::RenderLayerBacking::updateDirectlyCompositedBackgroundColor): LayoutTests: * compositing/backgrounds/negative-z-index-behind-body-expected.html: Added. * compositing/backgrounds/negative-z-index-behind-body-non-propagated-expected.html: Added. * compositing/backgrounds/negative-z-index-behind-body-non-propagated.html: Added. * compositing/backgrounds/negative-z-index-behind-body.html: Added. git-svn-id: http://svn.webkit.org/repository/webkit/trunk@208981 268f45cc-cd09-0410-ab3c-d52691b4dbfc
1 parent bf4bb3a commit 721cb2a

9 files changed

+140
-14
lines changed

LayoutTests/ChangeLog

+13
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,16 @@
1+
2016-11-26 Simon Fraser <[email protected]>
2+
3+
Composited negative z-index elements are hidden behind the body sometimes
4+
https://bugs.webkit.org/show_bug.cgi?id=165080
5+
rdar://problem/22260229
6+
7+
Reviewed by Zalan Bujtas.
8+
9+
* compositing/backgrounds/negative-z-index-behind-body-expected.html: Added.
10+
* compositing/backgrounds/negative-z-index-behind-body-non-propagated-expected.html: Added.
11+
* compositing/backgrounds/negative-z-index-behind-body-non-propagated.html: Added.
12+
* compositing/backgrounds/negative-z-index-behind-body.html: Added.
13+
114
2016-11-26 Simon Fraser <[email protected]>
215

316
Convert testharnessreport.js to LF linebreaks, from CRLF, which broke patches.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<style>
2+
.green {
3+
background-color: green;
4+
width: 200px;
5+
height: 200px;
6+
}
7+
</style>
8+
<body>
9+
<div class="green"></div>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<style>
2+
html {
3+
background: gray;
4+
}
5+
body {
6+
background: silver;
7+
}
8+
9+
div {
10+
position: absolute;
11+
z-index: -1;
12+
}
13+
.green {
14+
background-color: green;
15+
width: 200px;
16+
height: 200px;
17+
}
18+
</style>
19+
<body>
20+
<div class="green"></div>
21+
<div></div>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<style>
2+
html {
3+
background: gray;
4+
}
5+
body {
6+
position: relative;
7+
background: silver;
8+
}
9+
10+
div {
11+
position: absolute;
12+
z-index: -1;
13+
transform: translateZ(0);
14+
}
15+
.green {
16+
background-color: green;
17+
width: 200px;
18+
height: 200px;
19+
}
20+
</style>
21+
<body>
22+
<div class="green"></div>
23+
<div></div>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<style>
2+
body {
3+
position: relative;
4+
background: white;
5+
}
6+
7+
div {
8+
position: absolute;
9+
z-index: -1;
10+
transform: translateZ(0);
11+
}
12+
13+
.green {
14+
background-color: green;
15+
width: 200px;
16+
height: 200px;
17+
}
18+
</style>
19+
<body>
20+
<div class="green"></div>
21+
<div></div>

Source/WebCore/ChangeLog

+30
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,33 @@
1+
2016-11-26 Simon Fraser <[email protected]>
2+
3+
Composited negative z-index elements are hidden behind the body sometimes
4+
https://bugs.webkit.org/show_bug.cgi?id=165080
5+
rdar://problem/22260229
6+
7+
Reviewed by Zalan Bujtas.
8+
9+
If the <body> falls into the "directly composited background color" code path
10+
(say, because it's composited because of composited negative z-index children,
11+
and has content of its own), then we failed to take root background propagation
12+
into account, and put the opaque root background color on the body's layer.
13+
14+
Fix by sharing some code from RenderBox related to whether the body's renderer
15+
paints its background.
16+
17+
Tests cover the buggy case, and the case where the <html> has its own background color.
18+
19+
Tests: compositing/backgrounds/negative-z-index-behind-body-non-propagated.html
20+
compositing/backgrounds/negative-z-index-behind-body.html
21+
22+
* rendering/RenderBox.cpp:
23+
(WebCore::RenderBox::paintsOwnBackground):
24+
(WebCore::RenderBox::paintBackground):
25+
(WebCore::RenderBox::backgroundIsKnownToBeOpaqueInRect):
26+
(WebCore::skipBodyBackground): Deleted.
27+
* rendering/RenderBox.h:
28+
* rendering/RenderLayerBacking.cpp:
29+
(WebCore::RenderLayerBacking::updateDirectlyCompositedBackgroundColor):
30+
131
2016-11-25 Myles C. Maxfield <[email protected]>
232

333
[CSS Font Loading] FontFace.load() promises don't always fire

Source/WebCore/rendering/RenderBox.cpp

+19-13
Original file line numberDiff line numberDiff line change
@@ -130,17 +130,6 @@ static void removeControlStatesForRenderer(const RenderBox& renderer)
130130

131131
bool RenderBox::s_hadOverflowClip = false;
132132

133-
static bool skipBodyBackground(const RenderBox* bodyElementRenderer)
134-
{
135-
ASSERT(bodyElementRenderer->isBody());
136-
// The <body> only paints its background if the root element has defined a background independent of the body,
137-
// or if the <body>'s parent is not the document element's renderer (e.g. inside SVG foreignObject).
138-
auto documentElementRenderer = bodyElementRenderer->document().documentElement()->renderer();
139-
return documentElementRenderer
140-
&& !documentElementRenderer->hasBackground()
141-
&& (documentElementRenderer == bodyElementRenderer->parent());
142-
}
143-
144133
RenderBox::RenderBox(Element& element, RenderStyle&& style, BaseTypeFlags baseTypeFlags)
145134
: RenderBoxModelObject(element, WTFMove(style), baseTypeFlags)
146135
{
@@ -1383,16 +1372,33 @@ void RenderBox::paintBoxDecorations(PaintInfo& paintInfo, const LayoutPoint& pai
13831372
paintInfo.context().endTransparencyLayer();
13841373
}
13851374

1375+
bool RenderBox::paintsOwnBackground() const
1376+
{
1377+
if (isBody()) {
1378+
// The <body> only paints its background if the root element has defined a background independent of the body,
1379+
// or if the <body>'s parent is not the document element's renderer (e.g. inside SVG foreignObject).
1380+
auto documentElementRenderer = document().documentElement()->renderer();
1381+
return !documentElementRenderer
1382+
|| documentElementRenderer->hasBackground()
1383+
|| (documentElementRenderer != parent());
1384+
}
1385+
1386+
return true;
1387+
}
1388+
13861389
void RenderBox::paintBackground(const PaintInfo& paintInfo, const LayoutRect& paintRect, BackgroundBleedAvoidance bleedAvoidance)
13871390
{
13881391
if (isDocumentElementRenderer()) {
13891392
paintRootBoxFillLayers(paintInfo);
13901393
return;
13911394
}
1392-
if (isBody() && skipBodyBackground(this))
1395+
1396+
if (!paintsOwnBackground())
13931397
return;
1398+
13941399
if (backgroundIsKnownToBeObscured(paintRect.location()) && !boxShadowShouldBeAppliedToBackground(paintRect.location(), bleedAvoidance))
13951400
return;
1401+
13961402
paintFillLayers(paintInfo, style().visitedDependentColor(CSSPropertyBackgroundColor), style().backgroundLayers(), paintRect, bleedAvoidance);
13971403
}
13981404

@@ -1419,7 +1425,7 @@ bool RenderBox::getBackgroundPaintedExtent(const LayoutPoint& paintOffset, Layou
14191425

14201426
bool RenderBox::backgroundIsKnownToBeOpaqueInRect(const LayoutRect& localRect) const
14211427
{
1422-
if (isBody() && skipBodyBackground(this))
1428+
if (!paintsOwnBackground())
14231429
return false;
14241430

14251431
Color backgroundColor = style().visitedDependentColor(CSSPropertyBackgroundColor);

Source/WebCore/rendering/RenderBox.h

+3
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,9 @@ class RenderBox : public RenderBoxModelObject {
5656
}
5757

5858
bool backgroundIsKnownToBeOpaqueInRect(const LayoutRect& localRect) const final;
59+
60+
// Returns false for the body renderer if its background is propagated to the root.
61+
bool paintsOwnBackground() const;
5962

6063
// Use this with caution! No type checking is done!
6164
RenderBox* firstChildBox() const;

Source/WebCore/rendering/RenderLayerBacking.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -1809,7 +1809,7 @@ Color RenderLayerBacking::rendererBackgroundColor() const
18091809

18101810
void RenderLayerBacking::updateDirectlyCompositedBackgroundColor(bool isSimpleContainer, bool& didUpdateContentsRect)
18111811
{
1812-
if (!isSimpleContainer) {
1812+
if (!isSimpleContainer || (is<RenderBox>(renderer()) && !downcast<RenderBox>(renderer()).paintsOwnBackground())) {
18131813
m_graphicsLayer->setContentsToSolidColor(Color());
18141814
return;
18151815
}

0 commit comments

Comments
 (0)