w3c / svgwg

SVG Working Group specifications
Other
710 stars 133 forks source link

Clarify behavior of pointer-events on nested elements #744

Open yi-gu opened 5 years ago

yi-gu commented 5 years ago

Link to the spec: https://svgwg.org/svg2-draft/interact.html#PointerEventsProperty

The spec does not mention how the pointer-events property in descendants [gets inherited from] or [overrides] the one from their ancestor. e.g.

<div id='parent' style='pointer-events: none'>
  <div id='child'></div>
</div>

In this example, the pointer-events property in the child is inherited to be none. However, when the elements are iframes:

<iframe id='parent' style='pointer-events: none' src=''>
  <iframe id='child' src=''></iframe>
</iframe>

The pointer-events property does not get propagated.

If the nested element has its own pointer-events property, the behavior is also inconsistent between divs and iframes. e.g.

<div id='parent' style='pointer-events: none'>
  <div id='child' style='pointer-events: auto'></div>
</div>

In this example, auto in the child overrides none from the parent. For iframes:

<iframe id='parent' style='pointer-events: none' src=''>
  <iframe id='child' style='pointer-events: auto' src=''></iframe>
</iframe>

child will not accept events. See example here. This behavior makes sense because page owners will lose the control of the outer iframe if the inner one could override the decision on whether the region can accept events (especially for cross origin iframes).

It seems like the pointer-events propagation stops at the iframe level. In the following example:

<div id='parent' style='pointer-events: none'>
  <iframe id='child' style='pointer-events: auto'></iframe>
</div>

child will accept events because it overrides the property from the parent. See example here.

The existing behavior mentioned above is consistent in Chrome, Firefox and Safari. The specification needs to clarify it.

fsoder commented 5 years ago

It may be worth to start by noting that the SVG specification does not claim to specify behavior for non-SVG elements (note how "Applies to" only lists SVG elements) - pointer-events on anything else is currently a de-facto standard without a specification (there has been intentions to move it to css-ui but nothing has happened there AFAICT). It seems a tall order to require SVG to specify hit-testing for the CSS box model and how that interacts with pointer-events.

But to try and answer some of your questions... based on what the SVG spec says. pointer-events is an inherited property, which defines exactly how it is propagated (inherited) to the descendants, so unless cascading produces a value they inherit the value from the ancestor. When you start to mix in <iframe>s you get another document, and CSS does not cross into that document, hence the value would not be "propagated". Given that <iframe>s are replaced content though, the waters are potentially a bit murky as to what should happen in that case. In general though comparing <div>s with <iframe>s will largely be like comparing apples and oranges.

In the nested <div>s case we could reason about what geometry they have (this is a basic property of SVG hit-testing works). So the boxes likely have geometry in the form of, uhm, boxes. Per SVG[1], you'd pick the top-most target, so for the nested <div>s (which have nothing that changes z-ordering) that would mean the #child is on top, and is allowed to receive "pointer events" (pointer-events is not none).

Since <iframe>s are replaced content they would essentially be considered to be "black boxes". They would still have their CSS box geometry in the document they are in, but how (and if) they forward anything would be a detail of the specific replaced content I think (but that is really not specified anywhere).

[1] https://svgwg.org/svg2-draft/interact.html#PointerEvents

AmeliaBR commented 5 years ago

I made a CSS issue (since there didn't seem to be one) about getting a proper spec of `pointer-events): w3c/csswg-drafts#4438

I suppose we could add some text to the SVG spec about how to handle nested CSS layout boxes with a <foreignObject> construct, but I don't really want to get into the kind of detail discussed here. I'd rather see this properly defined in a general CSS spec & then we can reopen this discussion.

(But yes, there is no inheritance of CSS properties to iframes. The So the question is whether pointer-events affects the event retargetting that happens as a click bubbles in and out of the iframe from the parent document.)

css-meeting-bot commented 5 years ago

The SVG Working Group just discussed Clarify behavior of pointer-events on nested elements, and agreed to the following:

The full IRC log of that discussion <myles_> Topic: Clarify behavior of pointer-events on nested elements
<AmeliaBR> github: none
<myles_> GitHub: https://github.com/w3c/svgwg/issues/744
<myles_> AmeliaBR: This isn't actually an SVG issue. It's about the pointer events property and how it behaves on divs and iframes. That shouldn't be an SVG spec issue except for the fact that right now the only place the poitner events CSS property is normatively defined is in SVG. Even though all browsers support it on regular CSS boxes. I opened a CSS issue, but I'd like to to get a resolution from SVG to ask CSS to spec the pointer events property so they can
<myles_> answer these kinds of questions
<myles_> krit: CSS-ui spec used to have pointer-events defined, but was removed. Do you know why?
<myles_> AmeliaBR: I think because there was no agreement on a stable spec.
<myles_> chris: I think it was tantek who removed it. It was added for SVG but it was quietly dropped without notifying us. I'm trying to find the revision.
<myles_> AmeliaBR: It was a ways back, and hasn't been brought back in.
<myles_> krit: The request is to re-add it to a CSS spec.
<myles_> krit: This issue is something we can do with the SVG WG???
<myles_> AmeliaBR: We could spec something for divs and iframes, and in SVG we could talk about it in <foreignObject> and make rules for foreign content in SVG... and we could cover this case, but ....
<myles_> AmeliaBR: We're really not the best people to have this discussion.
<myles_> AmeliaBR: I would probably tend to want to say "wontfix as an SVG spec issue, but the SVG spec defers to a CSS spec about what to do about divs and iframes" But right now we don't have that CSS spec to defer to.
<myles_> krit: We could add a note that a future CSS spec will define this
<chris> "Dropping features that were not implemented, or were insufficiently implemented to exit CR. "
<chris> https://www.w3.org/TR/2015/CR-css-ui-3-20150707/#changes
<myles_> AmeliaBR: Adding a note sounds like a good idea. LIke a warning to both developers and authors and implementors that this property has an effect on non-SVG content, which is not defined here and a future spec that defines that might override the SVG-specific details. A note is a good idea.
<myles_> AmeliaBR: Let me look up what we already have in the spec....
<myles_> chris: I'm not finding anything since 2012 about pointer events in CSS
<myles_> AmeliaBR: Maybe nobody has dared touch it
<myles_> AmeliaBR: MDN just references the SVG spec. CSS index defers to the SVG spec. It might never have been written up anywhere for the general case
<myles_> krit: We can resolve on 2 things: 1) Request the CSS WG takes over the pointer events property 2) add a note to the SVG spec saying this might be overridden by a future CSS spec
<myles_> AmeliaBR: We have 1 paragraph about the content in <foreignObject> about hit testing, but no rules about pointer events values affect the foreign content
<chris> still not there, going back to 2004
<myles_> RESOLVED: Request the CSS WG takes over the pointer events property
<myles_> AmeliaBR: I volunteer to discuss this with CSSWG
<myles_> AmeliaBR: (but not to be an editor of the CSS spec)
<chris> https://bitsofco.de/theres-no-reason-to-use-pointer-events-for-html-elements/
<chris> "When used with non-SVG elements, only three values are available - inherit, auto and none."
<myles_> nzimmermann: If I inteprret the current spec correctly, if the <foreignObject> is treated as a rectangular area, everyting is done by object boudnign box, and doesn't consider content below it (flattened like an image). If we have further spec about the descendents of the foreign object, does this replace the current text about flattening for hit testing?
<myles_> AmeliaBR: That's what the second resolution would be. We would add a note about how this behaves for non-SVG content, but the CSS spec might change some of the details for SVG content.
<chris> (that page says "I don’t think there is a reason to use pointer-events for regular, interactive, HTML elements")
<myles_> AmeliaBR: 2 things to decide. We would have to be okay accepting changes that another spec imposes on us
<myles_> krit: (nzimmermann is from Igalia, joined SVGWG last week)
<chris> “The use of pointer-events in CSS for non-SVG elements is experimental. The feature used to be part of the CSS3 UI draft specification but, due to many open issues, has been postponed to CSS4.” — Mozilla MDN
<chris> https://css-tricks.com/almanac/properties/p/pointer-events/
<myles_> RESOLVED: Add a note to the SVG spec describing how behavior for pointer events will be defined in a yet-as-of-now unwritten CSS spec
<chris> https://caniuse.com/#feat=pointer-events
<chris> https://wiki.csswg.org/spec/css4-ui#pointer-events
<myles_> RESOLVED: Add a note to the SVG spec describing how behavior for the pointer-events property in foreign content will be defined in a yet-as-of-now unwritten CSS spec
<myles_> chris: I found documentation of why it was removed
<chris> Moved from CSS3-UI editor's draft because it was the top source of issues for the 2nd CSS3-UI LCWD, and because it requires documenting previously undocumented web platform hit-testing model.
<myles_> krit: <reads from history>
<myles_> chris: they removed it because it was a big source of issues in CSS3-UI, and it requires previously undocumented web platform testing model.
<myles_> AmeliaBR: We'll leave it to the CSS issue.
<myles_> krit: Anything else?