Skip to content

Commit

Permalink
[css-anchor-position-1] Fix flicker with try-option with fixed-positi…
Browse files Browse the repository at this point in the history
…on anchor

Previously we supposed the default anchor wouldn't change in
try-options, but the latest draft spec allows that.

When the currently tried option will use a default anchor that is
different from the currently used default anchor, checking overflow
with the snapshotted AnchorPositionScrollData will be incorrect,
and the incorrect results caused oscillation between try options.

To resolve that, when the total offset is requested for a different
default anchor, we need to calculate it on the fly instead of getting
it from the snapshotted result.

Also allow one more layout if ValidateSnapshot() (called after the
first layout in a document lifecycle update) finds that the
snapshotted scroll data needs update, to ensure correct layout and
paint with the changed anchor and scroll adjustment in most cases.

In rare cases when we need more than one additional layout to get
the stable layout, ShouldScheduleNextService() will schedule another
lifecycle.

Fixed: 338929745
Change-Id: I295fbc605ac8b7f0298eef7aeff4434c6bd54628
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5529048
Reviewed-by: Ian Kilpatrick <ikilpatrick@chromium.org>
Reviewed-by: Philip Rogers <pdr@chromium.org>
Commit-Queue: Xianzhu Wang <wangxianzhu@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1299608}
  • Loading branch information
wangxianzhu authored and chromium-wpt-export-bot committed May 11, 2024
1 parent d3dfe27 commit bba96a1
Show file tree
Hide file tree
Showing 4 changed files with 180 additions and 0 deletions.
@@ -0,0 +1,33 @@
<!doctype html>
<style>
body {
width: 150vw;
height: 150vh;
}
.anchor {
width: 50px;
height: 50px;
background: orange;
}
#anchor1 {
position: absolute;
top: 100px;
left: 350px;
}
#anchor2 {
position:fixed;
right: 0;
bottom: 0;
}
#anchored {
position: absolute;
top: 50px;
left: 350px;
width: 50px;
height: 50px;
background: blue;
}
</style>
<div class="anchor" id="anchor1"></div>
<div class="anchor" id="anchor2"></div>
<div id="anchored"></div>
57 changes: 57 additions & 0 deletions css/css-anchor-position/position-try-switch-from-fixed-anchor.html
@@ -0,0 +1,57 @@
<!doctype html>
<html class=reftest-wait>
<meta charset="utf-8">
<title>CSS Anchor Positioning Test: @position-try with different default anchors,
switching to fixed-position anchor on scroll and back on another scroll</title>
<link rel="help" href="https://drafts.csswg.org/css-anchor-position-1/#fallback-rule">
<link rel="match" href="position-try-switch-from-fixed-anchor-ref.html">
<script src="/common/reftest-wait.js"></script>
<script src="/common/rendering-utils.js"></script>
<style>
body {
width: 150vw;
height: 150vh;
}
.anchor {
width: 50px;
height: 50px;
background: orange;
}
#anchor1 {
anchor-name: --anchor1;
position: absolute;
top: 100px;
left: 350px;
}
#anchor2 {
anchor-name: --anchor2;
position:fixed;
right: 0;
bottom: 0;
}
#anchored {
position-anchor: --anchor1;
inset-area: top;
position-try-options: --fixed;
position: fixed;
width: 50px;
height: 50px;
background: blue;
}
@position-try --fixed {
inset-area: top left;
position-anchor: --anchor2;
}
</style>
<div class="anchor" id="anchor1"></div>
<div class="anchor" id="anchor2"></div>
<div id="anchored"></div>
<script>
waitForAtLeastOneFrame().then(() => {
window.scrollTo(250, 100);
waitForAtLeastOneFrame().then(() => {
window.scrollTo(0, 0);
takeScreenshot();
});
});
</script>
@@ -0,0 +1,37 @@
<!doctype html>
<meta charset="utf-8">
<style>
body {
width: 150vw;
height: 150vh;
}
.anchor {
width: 50px;
height: 50px;
background: orange;
}
#anchor1 {
position: absolute;
top: 100px;
left: 350px;
}
#anchor2 {
position:fixed;
right: 0;
bottom: 0;
}
#anchored {
position: fixed;
right: 50px;
bottom: 50px;
width: 50px;
height: 50px;
background: blue;
}
</style>
<div class="anchor" id="anchor1"></div>
<div class="anchor" id="anchor2"></div>
<div id="anchored"></div>
<script>
window.scrollTo(250, 100);
</script>
53 changes: 53 additions & 0 deletions css/css-anchor-position/position-try-switch-to-fixed-anchor.html
@@ -0,0 +1,53 @@
<!doctype html>
<html class=reftest-wait>
<meta charset="utf-8">
<title>CSS Anchor Positioning Test: @position-try with different default anchors, switching to fixed-position anchor on scroll</title>
<link rel="help" href="https://drafts.csswg.org/css-anchor-position-1/#fallback-rule">
<link rel="match" href="position-try-switch-to-fixed-anchor-ref.html">
<script src="/common/reftest-wait.js"></script>
<script src="/common/rendering-utils.js"></script>
<style>
body {
width: 150vw;
height: 150vh;
}
.anchor {
width: 50px;
height: 50px;
background: orange;
}
#anchor1 {
anchor-name: --anchor1;
position: absolute;
top: 100px;
left: 350px;
}
#anchor2 {
anchor-name: --anchor2;
position:fixed;
right: 0;
bottom: 0;
}
#anchored {
position-anchor: --anchor1;
inset-area: top;
position-try-options: --fixed;
position: fixed;
width: 50px;
height: 50px;
background: blue;
}
@position-try --fixed {
inset-area: top left;
position-anchor: --anchor2;
}
</style>
<div class="anchor" id="anchor1"></div>
<div class="anchor" id="anchor2"></div>
<div id="anchored"></div>
<script>
waitForAtLeastOneFrame().then(() => {
window.scrollTo(250, 100);
takeScreenshot();
});
</script>

0 comments on commit bba96a1

Please sign in to comment.