w3c / csswg-drafts

CSS Working Group Editor Drafts
https://drafts.csswg.org/
Other
4.52k stars 674 forks source link

[fullscreen] Details on how top layer elements interact with their ancestors #6939

Open nt1m opened 2 years ago

nt1m commented 2 years ago

Things it would be nice to get clarification on:

  1. Should top layer elements "escape" ancestor visibility? Currently they escape ancestor opacity/masks/overflow. Are there other properties they should escape? From the current spec, what "etc." is isn't clear:

    Ancestor elements with overflow, opacity, masks, etc. cannot affect it.

  2. What happens when the ancestor is replaced content or display: table-column? See the following tests:

  3. Should top layer elements "escape" ancestor pointer-events? In all 3 current implementations the answer is no, ancestor pointer-events propagate to <dialog>, would be nice to make that clear!

  4. Not sure "If it consists of multiple layout boxes, the first box is used." should be kept, this currently isn't tested, and is quite vague.

Personally, I don't find "It is rendered as an atomic unit as if it were a sibling of its root." very useful. The stacking context/containing block definitions sort of cover most things IMO.

Spec: https://fullscreen.spec.whatwg.org/#new-stacking-layer

Loirooriol commented 2 years ago

And from https://github.com/web-platform-tests/wpt/pull/31668#issuecomment-973982326, should top layer elements escape ancestor inertness?

emilio commented 2 years ago

Shouldn't this be in https://github.com/whatwg/fullscreen/issues/new?

nt1m commented 2 years ago

I think there was a resolution to move the top layer definition to CSSWG, I don't think this was ever done in practice though.

smfr commented 2 years ago

I would like to get a resolution on visibility at least, in the near future.

vmpstr commented 2 years ago

My view is that top layer elements should escape non-inherited ancestor properties/effects/clips. I'm not sure what escape visibility means in practice since visibility is inherited. IOW, I think visibility should have similar treatment to something like font-size in this case

tabatkins commented 2 years ago

Should top layer elements "escape" ancestor visibility? Currently they escape ancestor opacity/masks/overflow. Are there other properties they should escape? From the current spec, what "etc." is isn't clear:

Imo, they should act as if they were reparented to be siblings of the root element. That's how they exist in the box tree, and we shouldn't overcomplicate things (like we've done with some abspos+clipping stuff) by applying effects from elements that aren't in their box-tree ancestor chain.

visibility, as @vmpstr says, isn't a container effect, it just inherits down and affects each element individually. Inheritance still works as normal, so a top-layer element with a visibility: hidden ancestor (and no closer ancestor setting visible) will be hidden.

What happens when the ancestor is replaced content or display: table-column?

Same as previous answer - since it was reparented in the box tree, its container effects that would suppress rendering no longer apply. The top-layer elements should display in both of these cases, imo.

Should top layer elements "escape" ancestor pointer-events? In all 3 current implementations the answer is no, ancestor pointer-events propagate to

, would be nice to make that clear!

Like visibility, pointer-events isn't a container effect, just an inherited property, so it should continue to apply to the dialog as normal based on inheritance.

Not sure "If it consists of multiple layout boxes, the first box is used." should be kept, this currently isn't tested, and is quite vague.

Yeah this needs to be rewritten a little for clarity. It's just to address what we do if an element generates multiple sibling boxes; only the principal box is positioned by positioning schemes.

css-meeting-bot commented 2 years ago

The CSS Working Group just discussed how does top-layer interact with ancestors, and agreed to the following:

The full IRC log of that discussion <TabAtkins> Topic: how does top-layer interact with ancestors
<TabAtkins> github: https://github.com/w3c/csswg-drafts/issues/6939
<TabAtkins> smfr: top-laye ris used by <dialog>, ::backdrop,e tc
<TabAtkins> smfr: They generate new stackign contexts, escape ancestor opacity, other graphical effects
<TabAtkins> smfr: 'visibility' is a bit different
<TabAtkins> smfr: It's inherited; as specced, a visibility:hidden ancesotr will hide a dialog
<TabAtkins> [simon was dropped]
<TabAtkins> smfr: Tab responded with a confusing comment
<fantasai> TabAtkins: ...
<TabAtkins> smfr: he said top-layer things are reparented in the box tree
<TabAtkins> smfr: so that doesn't affect inheritance
<TabAtkins> smfr: I think people might be confused about that effect with visibility
<TabAtkins> smfr: Maybe UA stylesheet should put visibility:visible on the dialog?
<TabAtkins> ntim: Worth nothing - display:none on the ancestor propogates to the top-layer element
<TabAtkins> emilio: unsure to what extent display and visiblity work together
<TabAtkins> emilio: was going to suggest Simon's UA stylesheet tweak to make it work
<fantasai> TabAtkins: That seems fine to me. I don't see a particular issue to set 'visiblity' in the UA stylesheet
<fantasai> TabAtkins: I think it is surprising that a dialog would stay hidden if the ancestor is hidden
<TabAtkins> emilio: Seems like a special case, yeah. But other than that, no strong feeling.
<fantasai> TabAtkins: I guess 2 resolutions
<fantasai> TabAtkins: a) Top-layer elements are essentially reparented in the box tree, so visual effects from containers don't apply, but inheritance applies as normal
<fantasai> TabAtkins: b) We add rule to UA stylesheet that dialog is visibility: visible
<fantasai> emilio: I'm not super convinced we should add it
<fantasai> emilio: could argue the same for a ton of other properties
<fantasai> emilio: but not strong, so won't object
<fantasai> astearns: what other properties?
<TabAtkins> emilio: everything that inherits, like pointer-events
<TabAtkins> emilio: anything that inherits thru could potentially be weird
<TabAtkins> astearns: And we're onlyt alking about setting visibility and not display
<fantasai> TabAtkins: display is consistent with what I said because it can't be reparented in the box tree, because it's not in the box tree
<TabAtkins> astearns: So first proposal from tab is top-layer elements are reparented in teh box tree, and point out that inheritance isn't affected by that
<TabAtkins> smfr: The "etc" in the spec text needs clarification
<emilio> q+
<TabAtkins> TabAtkins: agree, can do that
<astearns> ack emilio
<TabAtkins> emilio: related to 'display' issue, something came up recently while triaging
<TabAtkins> emilio: Blink will create a box if the dialgo is a child of the replaced element
<fantasai> TabAtkins: I probably agree with you, decided on that in my comment too quickly. Because affects box generation, dialog shouldn't display at all
<TabAtkins> astearns: So any more discussion on the "reparenting in box tree" portion?
<fantasai> smfr: do we need to be that specific?
<fantasai> TabAtkins: You asked a bunch of questions, need to have consistent answers
<fantasai> TabAtkins: and having this conceptual model gives us consistent answers
<TabAtkins> ntim: I think stacking context/containing block dfns are enough to cover those cases
<fantasai> TabAtkins: Possibly
<fantasai> TabAtkins: I can review and see if that's enough
<fantasai> astearns: So why don't we not take that resolution for now, and you cna review
<TabAtkins> astearns: Okay so the etc
<fantasai> ntim: pointer-events
<fantasai> TabAtkins: It's an inherited property, so will just inherit. Unless we want to do a reset in the UA stylesheet
<fantasai> astearns: Do we need to resolve on resetting visibility?
<fantasai> TabAtkins: OK, let's do that
<fantasai> astearns: Proposed to have UA stylesheet reset visibility for dialog ... what about other top-level elements?
<fantasai> TabAtkins: Can't for other elements, can be arbitrary elements
<fantasai> TabAtkins: so can only do for dialog
<fantasai> astearns: OK, so proposed is that UA stylesheet sets 'visibility' on dialog
<fantasai> smfr: when they are in the modal state
<fantasai> fantasai: I believe there's a :modal pseudo-class in HTML
<fantasai> ntim: we have a pseudo-class, but internal, not exposed in CSS
<fantasai> iank_: I wrote that internal class
<fantasai> iank_: Wording is there, but not actually in the HTML spec
<fantasai> astearns: Anything else we can use to select?
<fantasai> TabAtkins: reasons we don't want to go into, are they blockers to putting in HTML spec or historical?
<fantasai> iank_: There was pushback to adding as an actual pseudo-class
<smfr> q+
<fantasai> iank_: HTML spec didn't want to define pseudo-classes itself
<fantasai> TabAtkins: put it in Selectors
<fantasai> ntim: UA stylesheet, should have a statement about it
<astearns> ack smfr
<fantasai> smfr: Comment about ::backdrop
<fantasai> smfr: current behavior, if have visiblity:hidden ancestor on dialog
<fantasai> smfr: is that dialog is hidden but backdrop shows up
<fantasai> smfr: because backdrop not affected by inherted visibility, that's not great
<fantasai> TabAtkins: right, because ::backdrop inherits from the root
<fantasai> emilio: I thought it didn't inherit, which causes problems with system properties
<fantasai> rune: ...
<iank_> https://html.spec.whatwg.org/#phrasing-content-3 and scroll up
<fantasai> emilio: Which is something we may want to consider fixing
<fantasai> TabAtkins: That can be done in today's CSS by setting 'all: initial' in the ::backdrop stylesheet
<fantasai> TabAtkins: so explainable in current CSS
<fantasai> emilio: is it though?
<iank_> "The dialog element, when its is modal flag is true, is expected to act as if it had a user-agent-level style sheet rule setting the following properties:"
<fantasai> emilio: all doesn't reset custom properties
<fantasai> emilio: We have an agenda item about selection, e.g. new ::selection model not inheriting from original element which causes other issues
<fantasai> iank_: Quoted the prose from HTML
<fantasai> TabAtkins: HTMl spec says "pretend there's a pseudo-class, and apply these properties"
<fantasai> TabAtkins: let's just define the pseudo-class
<fantasai> iank_: Pushback was exposing the internal pseudo-class to web developers
<fantasai> astearns: Is there a concern about exposing to web devs?
<fantasai> emilio: I think Gecko was the first to implement via internal pseudo-class
<fantasai> emilio: Everyone converged on that model
<fantasai> emilio: I think at first there was some resistance to expose a pseudo-class because not how some browsers work
<fantasai> emilio: but at this point, given we have interop in that sense, all browsers have internal pseudo-class
<fantasai> emilio: maybe makes sense to expose it
<fantasai> iank_: Agree it makes sense, but think we'll still get pushback from WHATWG
<fantasai> iank_: Another thing that could be internal class but isn't
<fantasai> TabAtkins: we don't have to invoke WHATWG, we just put it in Selectors
<fantasai> TabAtkins: as long as browsers want that, not a jurisdictional problem
<fantasai> emilio: ...
<fantasai> TabAtkins: To change the styling of a dialog based on whether it's open in a modal style or not, if UA wants to do it don't see why authors wouldn't want to do it
<fantasai> ntim: I don't see much use case for it
<fantasai> ntim: Unlikely that someone will call showModal() and show() on the same dialog
<fantasai> astearns: I suggest we separate out whether propertly-defined pseudo into own issue
<fantasai> astearns: but whether or not we do that, we should define certain things for dialog using existing internal pseudo-class
<fantasai> astearns: so have some changes mentioning that you set visiblity and perhaps pointer-events
<fantasai> astearns: using same handwavy definition that HTML currently has
<fantasai> astearns: and separately figure out whether we need an exposed real pseudo-class to put into Selectors
<fantasai> astearns: does that sound reasonable?
<fantasai> TabAtkins: OK, opening issue
<fantasai> astearns: So can we resolve to set visiblity using internal pseudo-class?
<fantasai> astearns: Anyone want to continue discussing? Anyone have an objection?
<fantasai> [continued silence]
<fantasai> RESOLVED: Set visiblity:hidden on modal dialogs
<fantasai> astearns: Any other property to resolve now, or continue discussing in the issue?
<fantasai> ntim: Pointer-events maybe?
<fantasai> ntim: Idk if it should be auto or all ...
<fantasai> astearns: In interest of time, let's punt to issue
<fantasai> astearns: and find out what the value should be and figure out any other properties that should be set in this way
<fantasai> astearns: Done with this issue for today
<fantasai> astearns: bit about box-tree reparenting, should that be a separate issue so don't lose track of it?
<TabAtkins> (new issue for :modal-dialog https://github.com/w3c/csswg-drafts/issues/6965)
<fantasai> astearns: OK, we'll keep this issue just about properties to set in UA stylesheet
<fantasai> astearns: separate issue on modal pseudo-class
<fantasai> astearns: and separate issue on reparenting
vmpstr commented 2 years ago
  • RESOLVED: Set visiblity:hidden on modal dialogs

Should that be visibility:visible?

Loirooriol commented 2 years ago

If modal dialogs reset pointer-events, then I guess they should escape ancestor inertness? Since inertness sets pointer-events: none. However, https://html.spec.whatwg.org/multipage/interaction.html#inert says

being part of a modal dialog does not "protect" a node from being marked inert

emilio commented 2 years ago

If modal dialogs reset pointer-events, then I guess they should escape ancestor inertness? Since inertness sets pointer-events: none. However, https://html.spec.whatwg.org/multipage/interaction.html#inert says

Why would it? We clarified that even though inertness behaves like pointer-events: none, it doesn't change the computed value, so they're not necessarily related.

We should probably fix up the previous resolution of course. Regarding these two tests:

2. What happens when the ancestor is replaced content or display: table-column? See the following tests:

   * [modal-dialog-in-replaced-renderer.html](https://github.com/web-platform-tests/wpt/blob/5874448f80/html/semantics/interactive-elements/the-dialog-element/modal-dialog-in-replaced-renderer.html)
   * [modal-dialog-in-table-column.html](https://github.com/web-platform-tests/wpt/blob/5874448f80139811704f009a2d5c232f2647db98/html/semantics/interactive-elements/the-dialog-element/modal-dialog-in-table-column.html)

I think consensus was that Gecko and WebKit have the preferred behavior since it's similar to how display: none suppresses descendant boxes. Perhaps we can resolve on that?

astearns commented 2 years ago
  • RESOLVED: Set visiblity:hidden on modal dialogs

Should that be visibility:visible?

Yes, there was a typo in the minutes

RESOLVED: Set visibility: visible on modal dialogs

astearns commented 2 years ago

There is now an issue on whether we need to define a real pseudo-class for this https://github.com/w3c/csswg-drafts/issues/6965

I suggest that if we would like to use box re-parenting to specify how top layers behave we also open a separate issue specifically on that.

The remainder of the discussion on this issue should be on which properties we need to set in the UA stylesheet for the dialog element shown state. One we have not yet resolved on is pointer-events. Please list any others we should consider.

Loirooriol commented 2 years ago

We clarified that even though inertness behaves like pointer-events: none, it doesn't change the computed value, so they're not necessarily related.

Yes, we don't have to necessarily reset inertness, but then pointer-events won't be reset, and if we decide to typically reset it, then it may be strange.

nt1m commented 2 years ago

We should probably fix up the previous resolution of course. Regarding these two tests:

2. What happens when the ancestor is replaced content or display: table-column? See the following tests:

   * [modal-dialog-in-replaced-renderer.html](https://github.com/web-platform-tests/wpt/blob/5874448f80/html/semantics/interactive-elements/the-dialog-element/modal-dialog-in-replaced-renderer.html)
   * [modal-dialog-in-table-column.html](https://github.com/web-platform-tests/wpt/blob/5874448f80139811704f009a2d5c232f2647db98/html/semantics/interactive-elements/the-dialog-element/modal-dialog-in-table-column.html)

I think consensus was that Gecko and WebKit have the preferred behavior since it's similar to how display: none suppresses descendant boxes. Perhaps we can resolve on that?

I made a WPT PR here: https://github.com/web-platform-tests/wpt/pull/32947 if everyone is ok with it, I can re-include them into interop-2022

josepharhar commented 2 years ago

I am implementing changes in chromium to get modal-dialog-in-replaced-renderer.html and modal-dialog-in-table-column.html passing again based on this resolution. However, it also caused these chromium-only tests to regress: https://source.chromium.org/chromium/chromium/src/+/main:third_party/blink/web_tests/fullscreen/rendering/backdrop-object.html https://source.chromium.org/chromium/chromium/src/+/main:third_party/blink/web_tests/fullscreen/rendering/backdrop-iframe.html

Should children of iframes and objects not be rendered in the top layer like children of content: url(...) and display:table-column? Should ::backdrop be given any special treatment when it is in the top layer when used like iframe::backdrop or object::backdrop? Should #displayTableColumn::backdrop be rendered where #displayTableColumn is display:table-column?

emilio commented 2 years ago

@josepharhar <iframe> and <object> are replaced elements, so I think the same resolution applies.

josepharhar commented 2 years ago

<iframe> and <object> are replaced elements, so I think the same resolution applies.

Cool, I am adding tests for this here: https://chromium-review.googlesource.com/c/chromium/src/+/3646687

As for my question about ::backdrop, I am moving the chrome-only tests to WPT in that change as well. Firefox and Chrome seem to have the same behavior there where iframe::backdrop and object::backdrop are rendered, so I am keeping it that way in chrome and keeping the test the same. Safari doesn't support requestFullscreen() it seems.