Skip to content

[selectors] Add :modal-dialog pseudo-class #6965

Closed

Description

@tabatkins

HTML defines that the <dialog> element has an "is modal" flag, and uses that as a styling hook. We just discussed adding some more properties to modal dialogs in the UA stylesheet, which would need to do the same.

This should just be handled as a real pseudo-class, rather than an abstract "pretend these styles were applied as if from the UA stylesheet".

@emilio @bfgeek @smfr

Activity

  1. bfgeek commented on Jan 19, 2022

    @bfgeek
  2. bfgeek commented on Jan 19, 2022

    @bfgeek
  3. mfreed7 commented on Jan 19, 2022

    @mfreed7
    Contributor

    I'm strongly in favor of exposing a pseudo class for things in the top layer. So let's not call it :modal-dialog, let's call it :top-layer, and have it apply to modal <dialog>, full screen elements, and (in the future), anything else that is located in the top layer such as popup elements.

  4. tabatkins commented on Jan 19, 2022

    @tabatkins
    MemberAuthor

    That's not possible in general, since "being in the top layer" is something that should be doable from CSS.

    But we could certainly generalize it to anything built-in that forces itself (or at least defaults) into the top layer.

  5. vmpstr commented on Jan 19, 2022

    @vmpstr
    Member

    "being in the top layer" is something that should be doable from CSS.

    Just to confirm, that is currently not possible in CSS right? But you're saying that in the future we may be able to put something in the top layer via CSS?

  6. tabatkins commented on Jan 20, 2022

    @tabatkins
    MemberAuthor

    Yeah, it's been in the cards for a long time.

  7. mfreed7 commented on Jan 20, 2022

    @mfreed7
    Contributor

    @tabatkins are there any artifacts you can point to for that idea (CSS-based top layer access)? I'm working on a proposal for exactly that, but CSS seems like a hard way to do it. I'm looking at an HTML attribute. But I'd love to see what's already been thought through.

    Having said that, I don't see why there can't be a :top-layer pseudo. It would be independent from "how" an element gets to the top layer, right?

  8. vmpstr commented on Jan 20, 2022

    @vmpstr
    Member

    Having said that, I don't see why there can't be a :top-layer pseudo

    I think the hard part is something like

    div { top-layer: yes }
    div:top-layer { top-layer: no }
    
  9. mfreed7 commented on Jan 20, 2022

    @mfreed7
    Contributor

    Having said that, I don't see why there can't be a :top-layer pseudo

    I think the hard part is something like

    div { top-layer: yes }
    div:top-layer { top-layer: no }
    

    Precisely. You can't control access to the top layer via CSS, for this and other reasons, but I don't see why you can't select based on it.

  10. vmpstr commented on Jan 20, 2022

    @vmpstr
    Member

    Isn't it just the fact that you can have one but not both? That is, you either control access via CSS but can't select, or you can select but then you can't control access via CSS. I don't know what "other reasons" are though, so the choice of whether to allow selection or access is probably decided by something else

  11. SebastianZ commented on Jan 20, 2022

    @SebastianZ
    Contributor

    For reference, there's a discussion around selectors that depend on layout in #5979.

    Sebastian

  12. mfreed7 commented on Jan 20, 2022

    @mfreed7
    Contributor

    Isn't it just the fact that you can have one but not both? That is, you either control access via CSS but can't select, or you can select but then you can't control access via CSS. I don't know what "other reasons" are though, so the choice of whether to allow selection or access is probably decided by something else

    The basic issue is that the UA controls the top layer, and can “kick out” elements. E.g. both full screen elements and modal dialogs get forcibly removed from the top layer when you hit ESC. If access to the top layer were provided by CSS (say via a position:top-layer property), what would happen in this case? Would computedStyle still say position:top-layer? Worse, how would one re-request top layer access in this case? By removing the property and re-adding it? The issue is that CSS can’t really be modified by the UA. But if top layer access was provided by something like <div toplayer>, then the UA could just remove the attribute when needed.

  13. vmpstr commented on Jan 20, 2022

    @vmpstr
    Member

    I appreciate the difficulty in getting things into top layer with CSS. I'm just trying to reconcile this with @tabatkins reply that "top layer with CSS is probably coming". Adding a :top-layer selector is likely to cement the fact that we can't add things to top layer with CSS, so it's important to understand whether or not CSS will ever be able to add things to top layer :)

  14. tabatkins commented on Jan 20, 2022

    @tabatkins
    MemberAuthor

    There's been several issues discussing it, but the most relevant one is #4645.

    There's nothing inherently magical about the top layer. You can achieve identical effects today via the common strategy of putting elements as final direct children of body and abspos or fixposing them. The point of the top layer is just convenience - because we reparent the element's box, it avoids things like scrollable ancestor clips automatically so you can put the element where it's convenient rather than always making it a body child.

    So removing things from the top layer similarly isn't a property of "being in the top layer", but rather "being a UA-provided feature, and thus not necessarily something the page author knows about". We don't want the video fullscreen button to mess up the entire page unless the author specifically handled exitting fullscreen; similarly with modals. If the UA provides, the UA should take away as well, for good user experience. But browsers don't have the ability to automatically dismiss home-brewed dialogs that are just abspos divs living at the end of body, because that's done entirely by the page author and it's their responsibility to control it and dismiss it.


    So, yes, we can't have a selector that means "element is in the top layer" and a property that puts elements in the top layer. But we definitely want the latter, because it's a useful convenience primitive that has no reason not to be exposed to authors. And we don't actually need the former; what we need is a pseudo-class for detecting when a host-language specific element is in a host-language specific state that, as a side-effect, puts it in the top layer, because that's a useful semantic detail of the element's current state; that's completely doable. When a dialog is modal, when a video is fullscreened, etc. are all potentially foldable into here if we think it's useful.

  15. mfreed7 commented on Jan 21, 2022

    @mfreed7
    Contributor

    So there's something somewhat magical about the top layer. It provides a guaranteed-on-top paint order, regardless of max(z-index) on the page. And as such, it gets some special attention from the UA to make sure it's being managed for the user. For example, both fullscreen and <dialog> have explicit provisions for the UA taking action to close the fullscreen/dialog for the user. (For fullscreen here, and dialog here.) In either of those cases, that works because they're both controlled via JS. However, if you provide access to the top layer via a CSS property, similar concerns will exist: the UA will need the power to remove those elements from the top layer in some cases, even if a position:top-layer CSS rule still matches the element. And when that happens, how do things work? See the questions here.

  16. 69 remaining items

  17. nt1m commented on May 25, 2022

    @nt1m
    Member

    a UI state that shows certain sub-parts of a UI, intentionally makes inert the rest of the UI while showing the sub-part, and requires an intentional action from the user to dismiss it. The element when shown via showModal meets this definition; so does an alert or confirm box.

    Per that definition, fullscreen doesn't meet the definition - it does not "intentionally make inert the rest of the UI".

    It does make inert the rest of the UI in Chromium fwiw: https://source.chromium.org/chromium/chromium/src/+/main:third_party/blink/renderer/core/css/resolver/style_adjuster.cc;l=712-724;drc=164a13142f64c249d85e219cf745c371fc51b701

    I don't have a particular preference on whether this should be the case, though I guess it does make sense.

  18. mfreed7 commented on May 25, 2022

    @mfreed7
    Contributor

    It does make inert the rest of the UI in Chromium fwiw: https://source.chromium.org/chromium/chromium/src/+/main:third_party/blink/renderer/core/css/resolver/style_adjuster.cc;l=712-724;drc=164a13142f64c249d85e219cf745c371fc51b701

    Yes, I agree Chromium makes the page inert but is this in the fullscreen spec somewhere? I definitely could have missed it, but I don't think it talks about making the page inert.

    I'd agree that if this behavior is (or becomes) per-spec, then :modal should likely apply for fullscreen elements.

  19. chrishtr commented on May 25, 2022

    @chrishtr
    Contributor

    I filed issue #7311 for whether fullscreen should be modal. In the meantime let's remove fulllscreen from the :modal spec.

  20. chrishtr commented on May 25, 2022

    @chrishtr
    Contributor

    Reopening until the spec edit is made.

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