Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[css-contain] Container queries within display:none are difficult to implement #8197

Open
Loirooriol opened this issue Dec 7, 2022 · 5 comments

Comments

@Loirooriol
Copy link
Contributor

<style>
@container (width >= 0) {
  #target { --x: BAD; }
}
</style>
<div id="outer-container" style="container-type: inline-size; --x: GOOD">
  <div id="none" style="display: none">
    <div id="inner-container" style="container-type: inline-size">
      <div id="target"></div>
    </div>
  </div>
</div>
<script>
document.body.append(getComputedStyle(target).getPropertyValue('--x'));
</script>

The query container for #target is #inner-container, since it has the right container-type. However, it generates no box since it's inside a display: none subtree, so width >= 0 should be unknown and --x: BAD should not apply.

This is tricky to implement, though, because browsers typically avoid computing the style of elements inside display: none subtrees. So when collecting the rules for #target, we may not know the container-type for #inner-container, and thus not know whether to apply --x: BAD.

Currently,

  • WebKit implements it correctly.
  • Blink implements it partially: the testcase above is good, but adding this breaks it:
    getComputedStyle(document.getElementById("inner-container")).getPropertyValue('--x');
  • Firefox skips #inner-container and thinks that the query container is #outer-container.

In https://phabricator.services.mozilla.com/D164113 @emilio says

Our behavior doesn't seem too terrible to me. Maybe elements inside display: none subtrees should be considered to not have any container? Or maybe we should always match the query as "unknown", as that's really what's going on? I don't know.

@emilio
Copy link
Collaborator

emilio commented Dec 7, 2022

For the record, WebKit might implement this particular case correctly, but has similar issues, see bug 186882.

@emilio
Copy link
Collaborator

emilio commented Dec 7, 2022

Oh, though that was fixed, at some point, so nvm then. WebKit still fails this test tho :)

@andruud
Copy link
Member

andruud commented Dec 14, 2022

Blink implements it partially: the testcase above is good, but adding this breaks it [...]

Thanks, landed a fix for this now. (https://crbug.com/1399755).

[general issue]

The current spec intentionally has no special case directly on display:none, and instead delays dealing with that until container-query-evaluation time (via having a principle box or not). This is to get a "stable" container situation in display:none. I.e. the container (which is an element, not a layout box) is always the "intended" container, and not a "random" container outside of display:none.

A related point is that container selection intentionally doesn't care whether an element has a pricinple box or not. I.e. we can select the right container without building the layout tree. This is important for Blink, since we need to know if something is a container or not sufficiently early in the pipeline. (This may be besides the point of this issue, but who knows where the discussion will lead).

Firefox skips #inner-container and thinks that the query container is #outer-container.

I think we should avoid this behavior for the reasons I said. (#outer-container is not the intended container).

Maybe elements inside display: none subtrees should be considered to not have any container?

That on the other hand seems probably OK? Although gCS would be worse than it needs to be when only the querying element (and not the container) is in display:none. And it's possibly unfortunate for style queries. But at least it's stable.

@lilles
Copy link
Member

lilles commented Dec 14, 2022

Maybe elements inside display: none subtrees should be considered to not have any container?

That on the other hand seems probably OK? Although gCS would be worse than it needs to be when only the querying element (and not the container) is in display:none. And it's possibly unfortunate for style queries. But at least it's stable.

Yeah, I think it sounds counter-intuitive for style queries to stop them from having effect inside display:none when other styles match as usual.

@atanassov atanassov added this to Overflow in March 2023 VF2F Mar 7, 2023
@astearns astearns moved this from Overflow to Wednesday - Mar 22 in March 2023 VF2F Mar 9, 2023
@css-meeting-bot
Copy link
Member

The CSS Working Group just discussed [css-contain] Container queries within display:none are difficult to implement, and agreed to the following:

  • RESOLVED: elements within a display:none subtree have no parents that container queries can access
The full IRC log of that discussion <emeyer> oriol: Problem is that browsers tend to avoid computing style of elements inside a display: none subtree
<emeyer> …You can still force the computation with JS
<emeyer> …What should happen if one of these elements may have a container which is applying some rules conditionally, which may affect the comptued style you get?
<emeyer> …Gets more complicated if ancestor is a container or not
<emeyer> …In Blink, I think this was easier to implement per spec since it has some caching and first computation is cached
<emeyer> …That way we know if ancestors are containers or not
<emeyer> …Firefox doesn’t have this caching, so when it computes, the information isn’t stored in the element
<emeyer> …emilio didn’t think my patch to pass information around was the best
<emeyer> …Discussion agreed it was reasonable that an element in a display: none subtree should be treated as having no container
<emeyer> …This might not be good for style queries
<emeyer> emilio: Some of this is complexity specific to Firefox, but in general, some of this is very messy and not very interoperable
<emeyer> …I’m not a fan of adding complexity here
<emeyer> …We do something similar where older browsers do transforms on display: none elements as none
<emeyer> …I’d rather do the easy-to-implement thing instead of having extra complexity
<emeyer> …I don’t think it’s particularly useful to check elements based on container queries when the container isn’t there
<emeyer> …Any answer will be weird
<emeyer> astearns: Is there a way of having elements escape a display: none ancestor using CSS?
<emeyer> emilio: No, which is why browsers optimize them away
<emeyer> astearns: Then I have no concerns
<emeyer> …Proposed resolution: elements within a display:none subtree have no parents that container queries can access
<emeyer> emilio: The wording could be they have no query containers, though I’d like room to confirm this is fine
<emeyer> …We can resolve and seek comment after
<emilio> s/room/Rune
<emeyer> astearns: Anyone on the call want to wait for Rune’s response?
<emeyer> (silence)
<emeyer> RESOLVED: elements within a display:none subtree have no parents that container queries can access

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
March 2023 VF2F
Wednesday - Mar 22
Development

No branches or pull requests

6 participants