w3c / csswg-drafts

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

[css-transforms-2] Handling of coplanar elements #1953

Open smfr opened 6 years ago

smfr commented 6 years ago

https://docs.google.com/document/d/1FIQW9qVPbZxn0pifFOXWWK0-7fXrjlSeYeZN7wHmIHo/edit#heading=h.rn2bkk7p8jvo

Both TR and ED required that planes that are co-planar shall stack in z-index order. It is impossible to implement because many functions available to transform yields irrational numbers that are not representable in floating point numbers, and is subject to rounding errors. Symbolic implementation is possible given the current function set, but is computationally expensive. Current implementation uses arbitrary threshold for coplanarity, but this practice creates more problems: 1. There is still a dilemma at the threshold. 2. The threshold is not documented nor standardized, and the way the threshold is defined depends on internal details.

Even if coplanarity can be computed cheaply, the tie breaking rule still causes performance problem. Consider the following example:

<div style=”transform-style:preserve-3d;”>
  <div style=”position:relative;”>A</div>
  <div style=”transform:translateZ(1px); will-change:transform;”>B</div>
  <div style=”position:relative;”>C</div>
</div>

Element A and C won’t be able to raster into the same texture cache, because transform animation on B may result in coplanarity with plane AC.

css-meeting-bot commented 6 years ago

The Working Group just discussed https://github.com/w3c/csswg-drafts/issues/1950.

The full IRC log of that discussion <chrishtr> topic:https://github.com/w3c/csswg-drafts/issues/1950
<chrishtr> github:https://github.com/w3c/csswg-drafts/issues/1950
<chrishtr> trchen:showing example of isolation:isolate parent with two 3d children with different z coordiante
<chrishtr> coordinate
<chrishtr> smfr: ED spec says that if the parent has content in its plane, then:
<chrishtr> smfr: in the same way that negative z-index children paint in front of the stacking context's background, but behind its foreground
<chrishtr> smfr: a natural extension to 3D is that the background of the parent is painted, then the "Foreground" content is a plane which is intersected with 3D child planes before flattening
<chrishtr> smfr: all content with any z-index is drawn together into the same plane
<chrishtr> smfr: all content without any 3D, that is
<chrishtr> trchen: then an element with preserve-3d will extend the 3d context to the parent
<chrishtr> smfr: it's common for sites to have a "card flip animation" effect in their UX. it looks wrong if that card intersects the background of the container, and maybe also the foreground
<chrishtr> smfr: so the proposal here might have compat problems
<chrishtr> smfr: alternate possibility is that the depth component is simply dropped and transforms become a "paint effect" that changes the output of its content
<chrishtr> trchen: chromium currently does the paint effect thing
<chrishtr> marakow: not sure about edge behavior with an example. card-flip cases had compat issue in the path
<chrishtr> past
<chrishtr> smfr: we need to do testing and choose based on compat concerns
<chrishtr> smfr: if you really want sorting of any kind with 3D transforms, use preserve-3d, otherwise we need to do something reasonable for compat
<chrishtr> trchen: flattening is really very related to stacking context, so it's hard to define things
<chrishtr> trchen: all elements have a screen transform matrix of some kind
<chrishtr> smfr: isolation implies flattening, so 3D children should be flattened into its plane
<chrishtr> trchen: but then how is the rendering matrix for those 3D children defined, since the containing block is above the isolation element?
<chrishtr> smfr: doesn't seem necessary to compute the root-relative matrix. can compute relative to its 3d context root only
<chrishtr> chrishtr: can we make the isolation element a containing block for 3d children?
<chrishtr> various: what about filters, opacity, etc?
<chrishtr> chrishtr: filter is already a containing block for all children in Mozilla
<dbaron> mozilla filter containing block changes were in https://bugzil.la/1125767 and https://bugzil.la/1187851
<chrishtr> smfr: should be able to compute the geometry one way or another
<chrishtr> gregwitworth: what are we trying to solve here?
<chrishtr> chrishr: ED spec is ill-defined, need to define somehow
<chrishtr> dbaron: spec should be clear. should keep things aligned with compat and developer expectations as much as possible
<chrishtr> smfr: web compat in this area may be bad enough that we can make what decision seems best
<chrishtr> ericwilligers: is it too late to make containing block and stacking context agree?
<chrishtr> trchen: too late to fix this
<chrishtr> smfr: containing block is for geometry, stacking context is for rendering
<chrishtr> marakow: these things may be corner cases, but web developers may be depending on them accidentally
<chrishtr> trchen: but they will get divergent behavior across browsers if they don't agree on compat
<smfr> i filed
<smfr> https://github.com/w3c/csswg-drafts/issues/1951
<chrishtr> github:https://github.com/w3c/csswg-drafts/issues/1951
<chrishtr> marakow:testcases are critical
<chrishtr> trchen: back to discussion about how to do overflow clip flattening without stacking context
<chrishtr> trchen: how should flattened result of 3d children sort against other children?
<mwoodrow> q+
<chrishtr> mwoodrow: in Mozilla in these cases, the overflow hidden element does not have preserve-3d on it
<chrishtr> mwoodrow: so it does not sort anything
<chrishtr> mwoodrow: in mozilla, the 3d child flattens itself
<chrishtr> mwoodrow: mozilla looks at the DOM parent to determine whether to avoid flattening
<smfr> i filed https://github.com/w3c/csswg-drafts/issues/1952 on the no-op div issue
<chrishtr> trchen: chromium flattens if the parent has positioning, is a stacking context or has clips, but not otherwise. this is a consequence of the implementation more than anything else
<chrishtr> smfr: making no-op parents flatten seems to be a breaking change
<chrishtr> mwoodrow: maybe not? Not aware of issues against Mozilla due to this behavior
<chrishtr> trchen: perhaps we can change transform-style to apply only if it's a stacking contet
<chrishtr> context
<chrishtr> trchen: fourth topic: coplanar planes is a computationally intractable issue
<chrishtr> trchen: because of floating-point accuracy issues
<smfr> filed https://github.com/w3c/csswg-drafts/issues/1953 on coplanar elements
<chrishtr> ericwilligers: found the animation example here compelling: don't want one frame of an animation where "coplanar" returns true
<chrishtr> github:https://github.com/w3c/csswg-drafts/issues/1953
<chrishtr> trchen: doesn't make sense to specify the epsilon for coplanarity, because of implementation difficulty
<dbaron> drawing #4 on the flipchart is https://lists.w3.org/Archives/Public/www-archive/2017Nov/att-0007/IMG_20171107_123911.jpg
<chrishtr> marakow: is the recommendation to say the behavior is undefined?
<chrishtr> trchen: yes
<chrishtr> marakow: should be able to define an epsilon
<chrishtr> trchen: two planes that are extremely close to the epsilon threshold may result in floating-point accuracy issues
<chrishtr> marakow: unspecified behavior does not achieve compat
<chrishtr> trchen: the ED spec has a TODO item to define subtree planes
<chrishtr> trchen: webkit and blink create a plane if there is any 3D transform.
<chrishtr> trchen: mozilla looks at the final matrix to see if there is 3D
<chrishtr> dbaron: thought the spec already said this?
<chrishtr> dbaron: seems good to match webkit/blink behavior for defining planes
<chrishtr> smfr: on coplanar: a good example of making things coplanar on purpose is a flipping card
<chrishtr> smfr: one way to implement is two elements, one of which flips relative to the other
<chrishtr> smfr: this will result in coplanarity numerical issues
<chrishtr> smfr: another way to do it is to put the transform on the container instead and flip it
<chrishtr> marakow: hit bugs where authors failed to specify backface-visibility:hidden and ended up with fighting/coplanar problems
<chrishtr> trchen: coplanar is not even what developers would want because it results in one thing always being on top
<chrishtr> trchen: I think we should make it undefined, and advise developers to not draw plans within these epsilons
<chrishtr> gregwhitworth: need to make things as specified as possible
<chrishtr> marakow: still think this should be specified, but ok to have a note in the spec that it's not a good idea to depend on exact behavior
<chrishtr> marakow: all of the items in the explainer are real and good to fix. but we need to do a lot more discussion based on testing and additional research to resolve them