Skip to content

Commit 7733484

Browse files
Paint transition pseudos on top of everything else in the scope.
Since crrev.com/1546589, the ::view-transition pseudo's PaintLayer is a child of the scope's PaintLayer. This patch implements custom paint order logic to ensure that the pseudo tree behaves like an overlay, regardless of any higher z-index that may be set on the scope's non-participating descendants. Also test the crash repro from https://crbug.com/445406431#comment3 (self-participating scope with high z-index child also participating). Bug: 421927605, 445406431 Change-Id: Ifac38969abbb82ea9a4ca67e6b03fffe99d52044 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7178180 Commit-Queue: Steve Kobes <[email protected]> Reviewed-by: Vladimir Levin <[email protected]> Cr-Commit-Position: refs/heads/main@{#1549132}
1 parent 0708ac5 commit 7733484

File tree

3 files changed

+119
-0
lines changed

3 files changed

+119
-0
lines changed
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<!DOCTYPE html>
2+
<html class="test-wait">
3+
<head>
4+
<style>
5+
6+
#scope {
7+
position: relative; width: 100px; height: 100px;
8+
background: #ddd; contain: strict;
9+
}
10+
#part {
11+
position: absolute; top: 10px; left: 10px;
12+
width: 80px; height: 80px; background: #8cf;
13+
z-index: 1; view-transition-name: foo;
14+
}
15+
16+
</style>
17+
</head>
18+
<body>
19+
<div id=scope><div id=part></div></div>
20+
<script>
21+
22+
onload = async () => {
23+
t = scope.startViewTransition(() => {});
24+
await t.finished;
25+
document.documentElement.classList.remove('test-wait');
26+
};
27+
28+
</script>
29+
</body>
30+
</html>
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<!DOCTYPE html>
2+
<style>
3+
#scope {
4+
position: relative; width: 200px; height: 100px;
5+
background: white; contain: strict;
6+
}
7+
#nonpart1 {
8+
position: absolute; top: 40px; left: 20px;
9+
width: 50px; height: 50px; background: #a4f;
10+
}
11+
#nonpart2 {
12+
position: absolute; top: 20px; left: 30px;
13+
width: 50px; height: 50px; background: #f88;
14+
}
15+
#vt {
16+
position: relative; width: 200px; height: 100px;
17+
top: -100px; background: rgba(0, 0, 0, 0.1);
18+
will-change: transform;
19+
}
20+
#part {
21+
position: absolute; top: 30px; left: 50px;
22+
width: 50px; height: 50px; background: #8cf;
23+
}
24+
25+
</style>
26+
<div id=scope>
27+
<div id=nonpart1></div>
28+
<div id=nonpart2></div>
29+
</div>
30+
<div id=vt>
31+
<div id=part></div>
32+
</div>
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
<!DOCTYPE html>
2+
<html class=reftest-wait>
3+
<head>
4+
<link rel="help" href="https://drafts.csswg.org/css-view-transitions-2/">
5+
<link rel="match" href="paint-order-ref.html">
6+
<script src="/common/reftest-wait.js"></script>
7+
<script src="/web-animations/testcommon.js"></script>
8+
<style>
9+
10+
#scope {
11+
position: relative; width: 200px; height: 100px;
12+
background: white; contain: strict;
13+
view-transition-name: none;
14+
}
15+
#part {
16+
position: absolute; top: 10px; left: 10px;
17+
width: 50px; height: 50px; background: #8cf;
18+
z-index: 1; view-transition-name: foo;
19+
}
20+
#higher-nonpart {
21+
position: absolute; top: 20px; left: 30px;
22+
z-index: 2; width: 50px; height: 50px; background: #f88;
23+
}
24+
#lower-nonpart {
25+
position: absolute; top: 40px; left: 20px;
26+
z-index: -1; width: 50px; height: 50px; background: #a4f;
27+
}
28+
::view-transition { background: rgba(0, 0, 0, 0.1); }
29+
::view-transition-group(*) { animation-play-state: paused; }
30+
::view-transition-new(*) {
31+
animation: unset; opacity: 1;
32+
transform: translateX(40px) translateY(20px);
33+
}
34+
::view-transition-old(*) { animation: unset; opacity: 0; }
35+
36+
</style>
37+
</head>
38+
<body>
39+
<div id=scope>
40+
<div id=part></div>
41+
<div id=higher-nonpart></div>
42+
<div id=lower-nonpart></div>
43+
</div>
44+
<script>
45+
46+
const scope = document.querySelector("#scope");
47+
failIfNot(scope.startViewTransition, "Missing element.startViewTransition");
48+
49+
async function runTest() {
50+
await waitForCompositorReady();
51+
scope.startViewTransition(() => requestAnimationFrame(takeScreenshot));
52+
}
53+
onload = () => runTest();
54+
55+
</script>
56+
</body>
57+
</html>

0 commit comments

Comments
 (0)