From 302fb98747b20a8b7b7d1610560cd1213608f20c Mon Sep 17 00:00:00 2001
From: Philip Rogers <pdr@chromium.org>
Date: Mon, 8 Apr 2024 17:08:48 +0000
Subject: [PATCH] Bug 1888944 [wpt PR 45451] - [css-anchor-position] Support
 basic position-visibility: anchors-visible, a=testonly

Automatic update from web-platform-tests
[css-anchor-position] Support basic position-visibility: anchors-visible

This patch implements basic support for position-visibility:
anchors-visible with a single anchor. There is active discussion about
whether to track the visibility of multiple anchors at:
https://github.com/w3c/csswg-drafts/issues/7758#issuecomment-2026137829.
The high-level approach in this patch is to use a post-layout
intersection observer for the tracked anchor. On visibility changes, the
anchored element's paint layer is updated via
`PaintLayer::SetInvisibleForPositionVisibility`.

Spec:
https://github.com/w3c/csswg-drafts/issues/7758#issuecomment-1965540529

Bug: 329703412
Change-Id: Icedcb43510a0c6a491cf463e7dc8a114ab7abf5f
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5410539
Commit-Queue: Xianzhu Wang <wangxianzhu@chromium.org>
Auto-Submit: Philip Rogers <pdr@chromium.org>
Reviewed-by: Xianzhu Wang <wangxianzhu@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1281911}

--

wpt-commits: 6673c544f6ecefa1e89dcd47db63b1c43a29396f
wpt-pr: 45451
---
 ...y-anchors-visible-after-scroll-in-ref.html | 32 +++++++++
 ...ors-visible-after-scroll-in.tentative.html | 64 +++++++++++++++++
 ...-anchors-visible-after-scroll-out-ref.html | 22 ++++++
 ...rs-visible-after-scroll-out.tentative.html | 59 ++++++++++++++++
 ...ity-anchors-visible-change-anchor-ref.html | 29 ++++++++
 ...chors-visible-change-anchor.tentative.html | 68 +++++++++++++++++++
 ...visible-non-intervening-container-ref.html | 10 +++
 ...e-non-intervening-container.tentative.html | 65 ++++++++++++++++++
 ...sition-visibility-anchors-visible-ref.html | 21 ++----
 ...chors-visible-with-position.tentative.html | 50 ++++++++++++++
 ...-visibility-anchors-visible.tentative.html | 39 +++++------
 ...visibility-remove-anchors-visible-ref.html | 25 +++++++
 ...lity-remove-anchors-visible.tentative.html | 61 +++++++++++++++++
 13 files changed, 505 insertions(+), 40 deletions(-)
 create mode 100644 testing/web-platform/tests/css/css-anchor-position/position-visibility-anchors-visible-after-scroll-in-ref.html
 create mode 100644 testing/web-platform/tests/css/css-anchor-position/position-visibility-anchors-visible-after-scroll-in.tentative.html
 create mode 100644 testing/web-platform/tests/css/css-anchor-position/position-visibility-anchors-visible-after-scroll-out-ref.html
 create mode 100644 testing/web-platform/tests/css/css-anchor-position/position-visibility-anchors-visible-after-scroll-out.tentative.html
 create mode 100644 testing/web-platform/tests/css/css-anchor-position/position-visibility-anchors-visible-change-anchor-ref.html
 create mode 100644 testing/web-platform/tests/css/css-anchor-position/position-visibility-anchors-visible-change-anchor.tentative.html
 create mode 100644 testing/web-platform/tests/css/css-anchor-position/position-visibility-anchors-visible-non-intervening-container-ref.html
 create mode 100644 testing/web-platform/tests/css/css-anchor-position/position-visibility-anchors-visible-non-intervening-container.tentative.html
 create mode 100644 testing/web-platform/tests/css/css-anchor-position/position-visibility-anchors-visible-with-position.tentative.html
 create mode 100644 testing/web-platform/tests/css/css-anchor-position/position-visibility-remove-anchors-visible-ref.html
 create mode 100644 testing/web-platform/tests/css/css-anchor-position/position-visibility-remove-anchors-visible.tentative.html

diff --git a/testing/web-platform/tests/css/css-anchor-position/position-visibility-anchors-visible-after-scroll-in-ref.html b/testing/web-platform/tests/css/css-anchor-position/position-visibility-anchors-visible-after-scroll-in-ref.html
new file mode 100644
index 00000000000000..10f74d4fb09852
--- /dev/null
+++ b/testing/web-platform/tests/css/css-anchor-position/position-visibility-anchors-visible-after-scroll-in-ref.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<style>
+  #scroll-container {
+    overflow: hidden scroll;
+    width: 300px;
+    height: 100px;
+  }
+
+  #anchor {
+    width: 100px;
+    height: 100px;
+    background: orange;
+    margin-bottom: 100px;
+  }
+
+  #target {
+    width: 100px;
+    height: 100px;
+    background: green;
+  }
+</style>
+
+<div id="scroll-container">
+  <div id="anchor">anchor</div>
+</div>
+<div id="target">target</div>
+
+<script>
+  const scroller = document.getElementById('scroll-container');
+  scroller.scrollTop = 0;
+</script>
diff --git a/testing/web-platform/tests/css/css-anchor-position/position-visibility-anchors-visible-after-scroll-in.tentative.html b/testing/web-platform/tests/css/css-anchor-position/position-visibility-anchors-visible-after-scroll-in.tentative.html
new file mode 100644
index 00000000000000..cea439c55f4a47
--- /dev/null
+++ b/testing/web-platform/tests/css/css-anchor-position/position-visibility-anchors-visible-after-scroll-in.tentative.html
@@ -0,0 +1,64 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<meta charset="utf-8">
+<meta name="assert" content="Scrolling an anchor in to view should cause a position-visibility: anchors-visible element to appear." />
+<title>CSS Anchor Positioning Test: position-visibility: anchors-visible</title>
+<link rel="help" href="https://github.com/w3c/csswg-drafts/issues/7758">
+<link rel="match" href="position-visibility-anchors-visible-after-scroll-in-ref.html">
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/rendering-utils.js"></script>
+<style>
+  #scroll-container {
+    overflow: hidden scroll;
+    width: 300px;
+    height: 100px;
+  }
+
+  #anchor {
+    anchor-name: --a1;
+    width: 100px;
+    height: 100px;
+    background: orange;
+  }
+
+  #spacer {
+    height: 100px;
+  }
+
+  #target {
+    position-anchor: --a1;
+    position-visibility: anchors-visible;
+    inset-area: block-end;
+    width: 100px;
+    height: 100px;
+    background: green;
+    position: absolute;
+    top: 0;
+    left: 0;
+  }
+</style>
+
+<div id="scroll-container">
+  <div id="anchor">anchor</div>
+  <div id="spacer"></div>
+  <div id="target">target</div>
+</div>
+
+<script>
+  // #target should be initially visible because it is anchored to #anchor,
+  // which is visible.
+  waitForAtLeastOneFrame().then(() => {
+    // Scroll #anchor out of view.
+    const scroller = document.getElementById('scroll-container');
+    scroller.scrollTop = 100;
+    // #target should now be invisible.
+
+    waitForAtLeastOneFrame().then(() => {
+      // Scroll #anchor back into view.
+      scroller.scrollTop = 0;
+
+      // #target should now be visible again.
+      takeScreenshot();
+    });
+  });
+</script>
diff --git a/testing/web-platform/tests/css/css-anchor-position/position-visibility-anchors-visible-after-scroll-out-ref.html b/testing/web-platform/tests/css/css-anchor-position/position-visibility-anchors-visible-after-scroll-out-ref.html
new file mode 100644
index 00000000000000..bd4fe1f09f8ae4
--- /dev/null
+++ b/testing/web-platform/tests/css/css-anchor-position/position-visibility-anchors-visible-after-scroll-out-ref.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<style>
+  #scroll-container {
+    overflow: hidden scroll;
+    width: 300px;
+    height: 100px;
+  }
+
+  #spacer {
+    height: 200px;
+  }
+</style>
+
+<div id="scroll-container">
+  <div id="spacer"><div>
+</div>
+
+<script>
+  const scroller = document.getElementById('scroll-container');
+  scroller.scrollTop = 100;
+</script>
diff --git a/testing/web-platform/tests/css/css-anchor-position/position-visibility-anchors-visible-after-scroll-out.tentative.html b/testing/web-platform/tests/css/css-anchor-position/position-visibility-anchors-visible-after-scroll-out.tentative.html
new file mode 100644
index 00000000000000..b2e3643b077cb2
--- /dev/null
+++ b/testing/web-platform/tests/css/css-anchor-position/position-visibility-anchors-visible-after-scroll-out.tentative.html
@@ -0,0 +1,59 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<meta charset="utf-8">
+<meta name="assert" content="Scrolling an anchor out of view should cause a position-visibility: anchors-visible element to disappear." />
+<title>CSS Anchor Positioning Test: position-visibility: anchors-visible</title>
+<link rel="help" href="https://github.com/w3c/csswg-drafts/issues/7758">
+<link rel="match" href="position-visibility-anchors-visible-after-scroll-out-ref.html">
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/rendering-utils.js"></script>
+<style>
+  #scroll-container {
+    overflow: hidden scroll;
+    width: 300px;
+    height: 100px;
+  }
+
+  #anchor {
+    anchor-name: --a1;
+    width: 100px;
+    height: 100px;
+    background: orange;
+  }
+
+  #spacer {
+    height: 100px;
+  }
+
+  #target {
+    position-anchor: --a1;
+    position-visibility: anchors-visible;
+    inset-area: bottom;
+    width: 100px;
+    height: 100px;
+    background: red;
+    position: absolute;
+    top: 0;
+    left: 0;
+  }
+</style>
+
+<div id="scroll-container">
+  <div id="anchor">anchor</div>
+  <div id="spacer"></div>
+  <div id="target">target</div>
+</div>
+
+<script>
+  // #target should be initially visible because it is anchored to #anchor,
+  // which is visible.
+
+  waitForAtLeastOneFrame().then(() => {
+    // Scroll #anchor so that it is out of view.
+    const scroller = document.getElementById('scroll-container');
+    scroller.scrollTop = 100;
+
+    // #target should now be invisible.
+    takeScreenshot();
+  });
+</script>
diff --git a/testing/web-platform/tests/css/css-anchor-position/position-visibility-anchors-visible-change-anchor-ref.html b/testing/web-platform/tests/css/css-anchor-position/position-visibility-anchors-visible-change-anchor-ref.html
new file mode 100644
index 00000000000000..cc35e4cd1f23e9
--- /dev/null
+++ b/testing/web-platform/tests/css/css-anchor-position/position-visibility-anchors-visible-change-anchor-ref.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<style>
+  #scroll-container {
+    overflow: hidden scroll;
+    width: 300px;
+    height: 100px;
+  }
+  #anchor {
+    width: 100px;
+    height: 200px;
+    background: orange;
+  }
+  #target {
+    width: 100px;
+    height: 100px;
+    background: green;
+  }
+</style>
+
+<div id="scroll-container">
+  <div id="anchor"></div>
+</div>
+<div id="target">target</div>
+
+<script>
+  const scroller = document.getElementById('scroll-container');
+  scroller.scrollTop = 100;
+</script>
diff --git a/testing/web-platform/tests/css/css-anchor-position/position-visibility-anchors-visible-change-anchor.tentative.html b/testing/web-platform/tests/css/css-anchor-position/position-visibility-anchors-visible-change-anchor.tentative.html
new file mode 100644
index 00000000000000..f8b1cc6d100f1a
--- /dev/null
+++ b/testing/web-platform/tests/css/css-anchor-position/position-visibility-anchors-visible-change-anchor.tentative.html
@@ -0,0 +1,68 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<meta charset="utf-8">
+<meta name="assert" content="Position-visibility should not be affected by the visibility of a previous anchor." />
+<title>CSS Anchor Positioning Test: position-visibility: anchors-visible</title>
+<link rel="help" href="https://github.com/w3c/csswg-drafts/issues/7758">
+<link rel="match" href="position-visibility-anchors-visible-change-anchor-ref.html">
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/rendering-utils.js"></script>
+<style>
+  #scroll-container {
+    overflow: hidden scroll;
+    width: 300px;
+    height: 100px;
+  }
+
+  .anchor {
+    width: 100px;
+    height: 100px;
+    background: orange;
+    display: inline-block;
+  }
+
+  #anchor1 {
+    height: 200px;
+    anchor-name: --a1;
+  }
+
+  #anchor2 {
+    anchor-name: --a2;
+  }
+
+  #target {
+    position-anchor: --a2;
+    position-visibility: anchors-visible;
+    inset-area: bottom;
+    width: 100px;
+    height: 100px;
+    background: green;
+    position: absolute;
+    top: 0;
+    left: 0;
+  }
+</style>
+
+<div id="scroll-container">
+  <div id="anchor1" class="anchor">anchor1</div>
+  <div id="anchor2" class="anchor">anchor2</div>
+  <div id="target">target</div>
+</div>
+
+<script>
+  // #target should be initially visible because it is anchored to #anchor2,
+  // which is visible.
+  waitForAtLeastOneFrame().then(() => {
+    // Change #target to be anchored to #anchor1.
+    target.style.positionAnchor = '--a1';
+    // #target should be still be visible because #anchor1 is also visible.
+    waitForAtLeastOneFrame().then(() => {
+      // Scroll #anchor2 out of view, with #anchor1 still in view.
+      const scroller = document.getElementById('scroll-container');
+      scroller.scrollTop = 100;
+      // #target should still be visible because it is anchored to #anchor1,
+      // which is still visible.
+      takeScreenshot();
+    });
+  });
+</script>
diff --git a/testing/web-platform/tests/css/css-anchor-position/position-visibility-anchors-visible-non-intervening-container-ref.html b/testing/web-platform/tests/css/css-anchor-position/position-visibility-anchors-visible-non-intervening-container-ref.html
new file mode 100644
index 00000000000000..3b6532e27b02a2
--- /dev/null
+++ b/testing/web-platform/tests/css/css-anchor-position/position-visibility-anchors-visible-non-intervening-container-ref.html
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<style>
+  #target {
+    width: 100px;
+    height: 100px;
+    background: green;
+  }
+</style>
+<div id="target">target</div>
diff --git a/testing/web-platform/tests/css/css-anchor-position/position-visibility-anchors-visible-non-intervening-container.tentative.html b/testing/web-platform/tests/css/css-anchor-position/position-visibility-anchors-visible-non-intervening-container.tentative.html
new file mode 100644
index 00000000000000..7b84976fd3af03
--- /dev/null
+++ b/testing/web-platform/tests/css/css-anchor-position/position-visibility-anchors-visible-non-intervening-container.tentative.html
@@ -0,0 +1,65 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<meta name="assert" content="position-visibility: anchors-visible should consider the visibility of the anchor relative the containing scroller, ignoring visibility in other scrollers." />
+<title>CSS Anchor Positioning Test: position-visibility: anchors-visible</title>
+<link rel="help" href="https://github.com/w3c/csswg-drafts/issues/7758">
+<link rel="match" href="position-visibility-anchors-visible-non-intervening-container-ref.html">
+<style>
+  #non-intervening-scroll-container {
+    overflow: hidden;
+    width: 200px;
+    height: 200px;
+    position: relative;
+  }
+
+  #position-container {
+    position: relative;
+  }
+
+  #scroll-container {
+    overflow: hidden scroll;
+    width: 400px;
+    height: 100px;
+  }
+
+  #anchor {
+    anchor-name: --a1;
+    width: 100px;
+    height: 100px;
+    background: orange;
+  }
+
+  #spacer {
+    height: 100px;
+  }
+
+  #target {
+    position-anchor: --a1;
+    position-visibility: anchors-visible;
+    inset-area: right;
+    width: 100px;
+    height: 100px;
+    background: green;
+    position: absolute;
+    top: 0;
+    left: 0;
+  }
+</style>
+
+<div id="non-intervening-scroll-container">
+  <div id="position-container">
+    <div id="scroll-container">
+      <!-- The anchor is not visible to the screen, but it is visible in the -->
+      <!-- containing block of anchor1 and target1, so the target should not -->
+      <!-- be hidden due to position-visibility: anchors-visible. -->
+      <div id="anchor">anchor</div>
+      <div id="spacer"></div>
+      <div id="target">target</div>
+    </div>
+  </div>
+</div>
+
+<script>
+  const non_intervening_scroller = document.getElementById('non-intervening-scroll-container');
+  non_intervening_scroller.scrollLeft = 100;
+</script>
diff --git a/testing/web-platform/tests/css/css-anchor-position/position-visibility-anchors-visible-ref.html b/testing/web-platform/tests/css/css-anchor-position/position-visibility-anchors-visible-ref.html
index 6f8d3cb971e6eb..17798173804b41 100644
--- a/testing/web-platform/tests/css/css-anchor-position/position-visibility-anchors-visible-ref.html
+++ b/testing/web-platform/tests/css/css-anchor-position/position-visibility-anchors-visible-ref.html
@@ -3,30 +3,17 @@
 <style>
   #scroll-container {
     overflow: hidden scroll;
-    width: 400px;
+    width: 300px;
     height: 100px;
   }
 
-  #contents-container {
-    height: 400px;
-  }
-
-  .anchor {
-    width: 100px;
-    height: 100px;
-    background: orange;
-    display: inline-block;
+  #spacer {
+    height: 200px;
   }
 </style>
 
 <div id="scroll-container">
-  <div id="contents-container">
-    <div class="anchor">anchor1</div>
-
-    <div class="anchor" style="height: 150px;">anchor2</div>
-
-    <div class="anchor" style="height: 150px;">anchor3</div>
-  </div>
+  <div id="spacer"></div>
 </div>
 
 <script>
diff --git a/testing/web-platform/tests/css/css-anchor-position/position-visibility-anchors-visible-with-position.tentative.html b/testing/web-platform/tests/css/css-anchor-position/position-visibility-anchors-visible-with-position.tentative.html
new file mode 100644
index 00000000000000..82eed0beb9d63a
--- /dev/null
+++ b/testing/web-platform/tests/css/css-anchor-position/position-visibility-anchors-visible-with-position.tentative.html
@@ -0,0 +1,50 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<meta name="assert" content="Position-visibility: anchors-visible should hide an element with an out-of-view anchor and a relpos scroller." />
+<title>CSS Anchor Positioning Test: position-visibility: anchors-visible</title>
+<link rel="help" href="https://github.com/w3c/csswg-drafts/issues/7758">
+<link rel="match" href="position-visibility-anchors-visible-ref.html">
+<style>
+  #scroll-container {
+    overflow: hidden scroll;
+    width: 300px;
+    height: 100px;
+    /* Same as position-visibility-anchors-visible.html, but with relpos here */
+    position: relative;
+  }
+
+  #anchor {
+    anchor-name: --a1;
+    width: 100px;
+    height: 100px;
+    background: orange;
+  }
+
+  #spacer {
+    height: 100px;
+  }
+
+  #target {
+    position-anchor: --a1;
+    position-visibility: anchors-visible;
+    inset-area: bottom right;
+    width: 100px;
+    height: 100px;
+    background: red;
+    position: absolute;
+    top: 0;
+    left: 0;
+  }
+</style>
+
+<div id="scroll-container">
+  <div id="anchor">anchor</div>
+  <div id="spacer"></div>
+  <div id="target">target</div>
+</div>
+
+<script>
+  const scroller = document.getElementById('scroll-container');
+  scroller.scrollTop = 100;
+  // #target should not be visible because #anchor is scrolled out of view.
+</script>
diff --git a/testing/web-platform/tests/css/css-anchor-position/position-visibility-anchors-visible.tentative.html b/testing/web-platform/tests/css/css-anchor-position/position-visibility-anchors-visible.tentative.html
index 6605bbc9783f8c..85b8d897db8cdc 100644
--- a/testing/web-platform/tests/css/css-anchor-position/position-visibility-anchors-visible.tentative.html
+++ b/testing/web-platform/tests/css/css-anchor-position/position-visibility-anchors-visible.tentative.html
@@ -1,55 +1,48 @@
 <!DOCTYPE html>
 <meta charset="utf-8">
+<meta name="assert" content="Position-visibility: anchors-visible should hide an element with an out-of-view anchor." />
 <title>CSS Anchor Positioning Test: position-visibility: anchors-visible</title>
 <link rel="help" href="https://github.com/w3c/csswg-drafts/issues/7758">
 <link rel="match" href="position-visibility-anchors-visible-ref.html">
 <style>
   #scroll-container {
     overflow: hidden scroll;
-    width: 400px;
+    width: 300px;
     height: 100px;
   }
 
-  #contents-container {
-    height: 400px;
-  }
-
-  .anchor {
+  #anchor {
+    anchor-name: --a1;
     width: 100px;
     height: 100px;
     background: orange;
-    display: inline-block;
   }
 
-  .target {
-    position: absolute;
+  #spacer {
+    height: 100px;
+  }
+
+  #target {
+    position-anchor: --a1;
     position-visibility: anchors-visible;
-    inset-area: block-end;
+    inset-area: bottom right;
     width: 100px;
     height: 100px;
     background: red;
+    position: absolute;
     top: 0;
     left: 0;
   }
 </style>
 
 <div id="scroll-container">
-  <div id="contents-container">
-    <!-- #target1 should not be visible because anchor is scrolled to not be visible. -->
-    <div class="anchor" style="anchor-name: --a1;">anchor1</div>
-    <div id="target1" class="target" style="position-anchor: --a1;">target1</div>
-
-    <!-- #target2 should not be visible because referenced name in anchor() is not visible. -->
-    <div class="anchor" style="anchor-name: --a2; height: 150px;">anchor2</div>
-    <div id="target2" class="target" style="position-anchor: --a2; top: anchor(--a1 bottom);">target2</div>
-
-    <!-- #target3 should not be visible because referenced name in anchor-size() is not visible. -->
-    <div class="anchor" style="anchor-name: --a3; height: 150px;">anchor3</div>
-    <div id="target3" class="target" style="position-anchor: --a3; min-width: anchor-width(--a1 width);">target3</div>
-  </div>
+  <div id="anchor">anchor</div>
+  <div id="spacer"></div>
+  <div id="target">target</div>
 </div>
 
 <script>
   const scroller = document.getElementById('scroll-container');
   scroller.scrollTop = 100;
+  // #target should not be visible because #anchor is scrolled out of view.
 </script>
diff --git a/testing/web-platform/tests/css/css-anchor-position/position-visibility-remove-anchors-visible-ref.html b/testing/web-platform/tests/css/css-anchor-position/position-visibility-remove-anchors-visible-ref.html
new file mode 100644
index 00000000000000..135763bf6bb8d7
--- /dev/null
+++ b/testing/web-platform/tests/css/css-anchor-position/position-visibility-remove-anchors-visible-ref.html
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<style>
+  #scroll-container {
+    overflow: hidden scroll;
+    width: 300px;
+    height: 100px;
+  }
+
+  #target {
+    width: 100px;
+    height: 100px;
+    margin-top: 100px;
+    background: green;
+  }
+</style>
+
+<div id="scroll-container">
+  <div id="target">target</div>
+</div>
+
+<script>
+  const scroller = document.getElementById('scroll-container');
+  scroller.scrollTop = 100;
+</script>
diff --git a/testing/web-platform/tests/css/css-anchor-position/position-visibility-remove-anchors-visible.tentative.html b/testing/web-platform/tests/css/css-anchor-position/position-visibility-remove-anchors-visible.tentative.html
new file mode 100644
index 00000000000000..c6649e5f93048e
--- /dev/null
+++ b/testing/web-platform/tests/css/css-anchor-position/position-visibility-remove-anchors-visible.tentative.html
@@ -0,0 +1,61 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<meta charset="utf-8">
+<meta name="assert" content="Removing position-visibility: anchors-visible from an invisible anchored element should cause it to become visible." />
+<title>CSS Anchor Positioning Test: position-visibility: anchors-visible</title>
+<link rel="help" href="https://github.com/w3c/csswg-drafts/issues/7758">
+<link rel="match" href="position-visibility-remove-anchors-visible-ref.html">
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/rendering-utils.js"></script>
+<style>
+  #scroll-container {
+    overflow: hidden scroll;
+    width: 300px;
+    height: 100px;
+  }
+
+  #anchor {
+    anchor-name: --a1;
+    width: 100px;
+    height: 100px;
+    background: orange;
+  }
+
+  #spacer {
+    height: 100px;
+  }
+
+  #target {
+    position-anchor: --a1;
+    position-visibility: anchors-visible;
+    inset-area: bottom;
+    width: 100px;
+    height: 100px;
+    background: green;
+    position: absolute;
+    top: 0;
+    left: 0;
+  }
+</style>
+
+<div id="scroll-container">
+  <div id="anchor">anchor</div>
+  <div id="spacer"></div>
+  <div id="target">target</div>
+</div>
+
+<script>
+  // #target should be initially visible because it is anchored to #anchor,
+  // which is visible.
+
+  // Scroll #anchor so that it is no longer visible.
+  const scroller = document.getElementById('scroll-container');
+  scroller.scrollTop = 100;
+
+  waitForAtLeastOneFrame().then(() => {
+    // Remove position-visibility: anchors-visible. #target should become
+    // visible again.
+    target.style.positionVisibility = 'initial';
+    takeScreenshot();
+  });
+</script>