Skip to content

[selectors] Add :open or :top-layer pseudo class #7319

Closed

Description

@mfreed7

The CSSWG recently resolved to add a :modal pseudo class that applies to elements that are "modal". That was general purpose, in that it should apply to anything that fits the description of being "modal", not just modal <dialog>.

Today, the OpenUI WC similarly resolved to add a :top-layer pseudo class that should apply to (at least) elements using the Popup API which are currently in the top layer. The intention for the naming and behavior, though, was that this pseudo class should also be general purpose. It should match any type of element in the top layer, including modal <dialog>, fullscreen elements, and ::backdrop pseudo elements. Also maybe Shared Element Transitions?

Thoughts?

Activity

  1. SebastianZ commented on May 27, 2022

    @SebastianZ
    Contributor

    If :top-layer is meant to be general purpose, should it always match the top-most element in the stacking context?

    Also, ::backdrop literally says that it is behind something, so I believe it shouldn't fall into that category.

    Sebastian

  2. Loirooriol commented on May 27, 2022

    @Loirooriol
    Contributor

    As mentioned in #6965, adding such selector would prevent allowing authors to place elements into the top layer via some CSS property. Or would this only match elements placed in the top layer by the UA?

    ::backdrop pseudo elements

    :top-layer is like *:top-layer where * matches elements, not pseudo-elements like ::backdrop. Do you mean ::backdrop:top-layer should match? But that's strange, because pseudo-elements can only be followed by user action pseudo-classes (https://drafts.csswg.org/selectors/#pseudo-element-states) and it seems pointless since ::backdrop only generates boxes if the originating element is in the top layer.

  3. nt1m commented on May 28, 2022

    @nt1m
    Member

    I don't like the name :top-layer because the top layer is an implementation detail. Developers should not know about such detail. A semantic name would be more appropriate.

  4. plinss commented on May 28, 2022

    @plinss
    Member

    :top-layer is also confusingly named as there can apparently be multiple 'top-layer's. Sometimes you need to know if an element is in a top-layer vs the top-most top-layer.

  5. mfreed7 commented on May 31, 2022

    @mfreed7
    ContributorAuthor

    :top-layer is like *:top-layer where * matches elements, not pseudo-elements like ::backdrop. Do you mean ::backdrop:top-layer should match? But that's strange, because pseudo-elements can only be followed by user action pseudo-classes (https://drafts.csswg.org/selectors/#pseudo-element-states) and it seems pointless since ::backdrop only generates boxes if the originating element is in the top layer.

    Sounds like there's generally some pushback to having this apply to ::backdrop pseudo elements, and I can see those points. I agree there's likely not much of a use case, since ::backdrop is always in the top layer. But is there any downside to making ::backdrop match :top-layer, to make it easier to explain? I.e. "anything in the top layer", rather than "anything in the top layer, except for ::backdrop pseudo elements, which are in the top layer but still don't match :top-layer"?

    I don't like the name :top-layer because the top layer is an implementation detail. Developers should not know about such detail. A semantic name would be more appropriate.

    Suggestions appreciated. Note that in OpenUI, we discussed this multiple times, and there were several suggestions, of which :top-layer won the vote. If there's a better name suggestion, let's discuss. One question though - the "top layer" isn't really an implementation detail, is it? To use it, developers need to know how it works, and it is fairly well specified.

    :top-layer is also confusingly named as there can apparently be multiple 'top-layer's. Sometimes you need to know if an element is in a top-layer vs the top-most top-layer.

    Yeah, I do think the multiple-top-layer thing is confusing in general. The "top-top-layer", which seems to be just for Shared Element Transitions, should likely get another name and another description. On the other hand, "top layer" is a spec-defined concept and this proposed pseudo class should be tied directly to that definition. Again, name suggestions appreciated.

    Side question: what's the use case for "needing to know if an element is in the top-layer vs. the top-most top-layer"?

  6. KennethHoff commented on May 31, 2022

    @KennethHoff

    First ever comment on csswg, but when I read the title, I thought :top-layer somehow referred to the top-most cascade layer.
    I think the word layer should maybe be "reserved" only for things relating to cascade layers, as I believe this can cause confusion

  7. Loirooriol commented on May 31, 2022

    @Loirooriol
    Contributor

    is there any downside to making ::backdrop match :top-layer, to make it easier to explain?

    ::backdrop may match ::backdrop:top-layer, but not :top-layer alone. Just like :hover can only select elements, even if ::before:hover is valid according to the spec. You would need something like **:top-layer from #4565 in order to simultaneously select elements and pseudo-elements.

  8. SebastianZ commented on May 31, 2022

    @SebastianZ
    Contributor

    it seems pointless since ::backdrop only generates boxes if the originating element is in the top layer.

    Sounds like there's generally some pushback to having this apply to ::backdrop pseudo elements, and I can see those points. I agree there's likely not much of a use case, since ::backdrop is always in the top layer. But is there any downside to making ::backdrop match :top-layer, to make it easier to explain? I.e. "anything in the top layer", rather than "anything in the top layer, except for ::backdrop pseudo elements, which are in the top layer but still don't match :top-layer"?

    While the Fullscreen spec. says that the ::backdrop pseudo-element is in the same top layer as the originating element, from an author's perspective ::backdrop is behind its originating element.

    Sebastian

  9. mfreed7 commented on Jun 1, 2022

    @mfreed7
    ContributorAuthor

    I think the word layer should maybe be "reserved" only for things relating to cascade layers, as I believe this can cause confusion

    I see the point - suggestions appreciated.

    ::backdrop may match ::backdrop:top-layer, but not :top-layer alone. Just like :hover can only select elements, even if ::before:hover is valid according to the spec. You would need something like **:top-layer from #4565 in order to simultaneously select elements and pseudo-elements.

    Right, I agree with this. I guess the confusing part might be if ::backdrop:not(:top-layer) matched the ::backdrop element. Because by definition ::backdrop is in the top layer. Seems like it should therefore match :top-layer, right?

    While the Fullscreen spec. says that the ::backdrop pseudo-element is in the same top layer as the originating element, from an author's perspective ::backdrop is behind its originating element.

    Right. But as you point out, it is in the top layer. Seems like it would make sense to have it match :top-layer then.


    I'm not strongly against having :top-layer not match ::backdrop from a use case point of view. I'm more arguing from a point of clarity about what it means to match :top-layer. Maybe there's a clean way to do that though. For the folks arguing against having ::backdrop match :top-layer, how would you define :top-layer? My preferred definition is "matches anything in the top layer".

  10. SebastianZ commented on Jun 1, 2022

    @SebastianZ
    Contributor

    While the Fullscreen spec. says that the ::backdrop pseudo-element is in the same top layer as the originating element, from an author's perspective ::backdrop is behind its originating element.

    Right. But as you point out, it is in the top layer. Seems like it would make sense to have it match :top-layer then.

    I guess, my question is, why does the Fullscreen spec. define that ::backdrop is in the top layer? And that the top layer can consist of multiple elements.

    Sebastian

  11. nt1m commented on Jun 1, 2022

    @nt1m
    Member

    While the Fullscreen spec. says that the ::backdrop pseudo-element is in the same top layer as the originating element, from an author's perspective ::backdrop is behind its originating element.

    Right. But as you point out, it is in the top layer. Seems like it would make sense to have it match :top-layer then.

    I guess, my question is, why does the Fullscreen spec. define that ::backdrop is in the top layer? And that the top layer can consist of multiple elements.

    Sebastian

    This is to prevent a random element outside the top layer with z-index: 999999 to appear above a ::backdrop.

  12. mfreed7 commented on Jun 1, 2022

    @mfreed7
    ContributorAuthor

    This is to prevent a random element outside the top layer with z-index: 999999 to appear above a ::backdrop.

    Right, or if you have nested popups/dialogs. The backdrop from the topmost dialog should be on top of the other (non-topmost) dialog.

  13. mfreed7 commented on Jun 1, 2022

    @mfreed7
    ContributorAuthor

    And that the top layer can consist of multiple elements.

    Nested elements is the answer here too. It's a semi-common use case. Like a dialog that has a tooltip on top. Both are in the top layer.

  14. nt1m commented on Jun 1, 2022

    @nt1m
    Member

    the "top layer" isn't really an implementation detail, is it?

    I don't think it's a concept that speaks for starters/most people. Web devs know that a certain element is fullscreen, or a certain dialog is open/modal. Blog posts might explain that those things appear on top of all other elements, but without mentioning "top layer". Also, there is the confusion that we had on the WebKit team, on whether an element is a top layer, or is part of a set of elements called "the top layer". I think this pseudo class also has this ambiguity, e.g. :modal means this element is modal, so by the logic :top-layer means: this element is a top layer.

    @mfreed7 I think the more important question here is: What use case does this solve for the Popup API?

    From what I can understand, we didn't go with something like :popup-open, in case a web developer wants to use a CSS transition to open the popup, where the closed state is not in the top layer, but the open state is. That design seems flawed to me, because I would expect the popup to be in the top layer while the transition is happening (regardless whether it is closing/opening), mainly because pushing/popping the top layer applies a couple of style adjustments, changes the stacking context, containing block, etc. which makes it inefficient to transition (and potentially could end up in broken results with the containing block changing during the transition).
    So if the popup is closing, the popup should only be removed from the top layer when the transition for closing is done. If implemented this way, the :top-layer pseudo class would still match even though the popup is closing...

    I generally think a :top-layer pseudo class should not exist, and instead the popup API use case should be addressed using something like :popup-open.

  15. mfreed7 commented on Jun 1, 2022

    @mfreed7
    ContributorAuthor

    I don't think it's a concept that speaks for starters/most people. Web devs know that a certain element is fullscreen, or a certain dialog is open/modal. Blog posts might explain that those things appear on top of all other elements, but without mentioning "top layer".

    I'm very open to suggestions for a better name.

    Also, there is the confusion that we had on the WebKit team, on whether an element is a top layer, or is part of a set of elements called "the top layer". I think this pseudo class also has this ambiguity, e.g. :modal means this element is modal, so by the logic :top-layer means: this element is a top layer.

    This is a really great point. My intention was for just the element itself to match :top-layer. I.e.,

    <dialog open><div></div></dialog>
    <script>
      document.querySelector('dialog').matches(':top-layer'); // true
      document.querySelector('div').matches(':top-layer'); // false
    </script>

    @mfreed7 I think the more important question here is: What use case does this solve for the Popup API?

    From what I can understand, we didn't go with something like :popup-open, in case a web developer wants to use a CSS transition to open the popup, where the closed state is not in the top layer, but the open state is. That design seems flawed to me, because I would expect the popup to be in the top layer while the transition is happening (regardless whether it is closing/opening), mainly because pushing/popping the top layer applies a couple of style adjustments, changes the stacking context, containing block, etc. which makes it inefficient to transition (and potentially could end up in broken results with the containing block changing during the transition). So if the popup is closing, the popup should only be removed from the top layer when the transition for closing is done. If implemented this way, the :top-layer pseudo class would still match even though the popup is closing...

    On the general question of how the Popup API will support animations, please see openui/open-ui#335, and in particular, this comment openui/open-ui#335 (comment). TL;DR, the Popup API will have a two-stage update for show/hide, which will allow animations to run after adding, or before removing, a popup from the top layer. As you mentioned, that means :top-layer will match during the transition. But that's actually the point - it is very ergonomic:

    [popup] {
      opacity: 0;
      transition: opacity 1s;
    }
    [popup]:top-layer {
      opacity: 1;
    }

    I generally think a :top-layer pseudo class should not exist, and instead the popup API use case should be addressed using something like :popup-open.

    Certainly just going with :popup-open achieves all of the use cases for the popup API. However, the resolution (#6965 (comment)) for :modal seems to indicate that CSSWG prefers to have more general pseudo classes for concepts. This would be exactly the opposite conclusion.

  16. 49 remaining items

  17. fantasai commented on Nov 11, 2022

    @fantasai
    Collaborator
  18. josepharhar commented on Feb 9, 2024

    @josepharhar
    Contributor

    FYI I am speccing this in HTML here: whatwg/html#10126

  19. josepharhar commented on Oct 15, 2024

    @josepharhar
    Contributor

    I opened a new issue about :closed because this doesn't have consensus yet: #11039

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions