[csswg-drafts] [css-contain] If a ResizeObserver callback changes the `content-visibility` of an element, should that prevent observations of the same resize event? (#7746)

mrobinson has just created a new issue for https://github.com/w3c/csswg-drafts:

== [css-contain] If a ResizeObserver callback changes the `content-visibility` of an element, should that prevent observations of the same resize event? ==
https://w3c.github.io/csswg-drafts/css-contain-2/#cv-notes states:

> From the perspective of a [ResizeObserver](https://w3c.github.io/csswg-drafts/resize-observer-1/#resizeobserver), the [skipped contents](https://w3c.github.io/csswg-drafts/css-contain-2/#skips-its-contents) of an element never change their size. If these elements become non-skipped later, the resize observation will be delivered if the new size differs from the last size used to notify the resize observer.

A `ResizeObsever` observation callback might change the `content-visibility` and force layout of an element though. Consider the situation where that freshly-hidden element also has a `ResizeObsever` triggered by the same resize event. The question here is whether a web engine should trigger an observation callback for the freshly-hidden element.

To me it seems like the specification implies that *immediately* after content is hidden it should stop receiving any `ResizeObserver` callbacks, but I believe that there could be multiple interpretations of the passage above.

cc @emilio

<details>
<summary>A WPT test demonstrating the situation</summary>

```html
<!doctype HTML>
<html>
<meta charset="utf8">
<title>Content Visibility: behavior of ResizeObserver that changes content-visibility</title>
<link rel="author" title="Martin Robinson" href="mailto:mrobinson@igalia.com">
<link rel="help" href="https://drafts.csswg.org/css-contain/#content-visibility">
<meta name="assert" content="ResizeObservers that modify content-visibility in observation callbacks should prevent observation of newly skipped content">

<style>
.hidden {
  content-visibility: hidden;
}

.resize > div {
    width: 100px;
}

</style>
<div id="container">
  <div id="resize">x</div>
  <div id="hidden">x</div>
</div>

<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>

<script>
async_test((t) => {
  async function runTest() {
    let didInitialCallback = false;
    let didHiddenCallback = false;
    let shouldHide = false;
    const container = document.getElementById("container");

    let resizeObserver = new ResizeObserver((entries) => {
      didInitialCallback = true;
      if (shouldHide) {
        container.classList.add("hidden");
        container.clientWidth;
      }
    });
    resizeObserver.observe(resize);

    let hiddenResizeObserver = new ResizeObserver((entries) => {
      didHiddenCallback = true;
    });
    hiddenResizeObserver.observe(hidden);

    await new Promise(requestAnimationFrame);

    assert_equals(didInitialCallback, true, 'Resize observation should happen in first frame after registering');
    assert_equals(didHiddenCallback, true, 'Resize observation should happen in first frame after registering');
    didInitialCallback = false;
    didHiddenCallback = false;

    container.classList.add("resize");
    await new Promise(requestAnimationFrame);

    assert_equals(didInitialCallback, true, 'Resize observation should happen after resizing.');
    assert_equals(didHiddenCallback, true, 'Resize observation should happen after resizing.');
    didInitialCallback = false;
    didHiddenCallback = false;
    shouldHide = true;

    // Change the size of all children of the container. This should cause a resize
    // observation, but only for the first resize observer, which immediately
    // hides the container, preventing the second observation.
    container.classList.remove("resize");
    await new Promise(requestAnimationFrame);

    assert_equals(didInitialCallback, true, 'Resize observation should happen after resizing.');
    assert_equals(didHiddenCallback, false, 'Resize observation should happen after resizing.');

    t.done();
  }

  window.onload = function() {
    requestAnimationFrame(() => requestAnimationFrame(runTest));
  };
}, "ResizeObserver observation prevented for content hidden in ResizeObserver callback");
</script>
</html>
```

</details>

Please view or discuss this issue at https://github.com/w3c/csswg-drafts/issues/7746 using your GitHub account


-- 
Sent via github-notify-ml as configured in https://github.com/w3c/github-notify-ml-config

Received on Thursday, 15 September 2022 09:18:14 UTC