W3C home > Mailing lists > Public > public-fx@w3.org > July to September 2016

Re: [css-transforms] CSS3D breaks with opacity flattening

From: /#!/JoePea <trusktr@gmail.com>
Date: Tue, 27 Sep 2016 11:15:38 -0700
Message-ID: <CAKU1PAW4JO7PvBKprW3ECBE1moZmpjMShayzgnJ-J3s5_pvgZg@mail.gmail.com>
To: Tien-Ren Chen <trchen@chromium.org>
Cc: Rik Cabanier <cabanier@gmail.com>, Matt Woodrow <mwoodrow@mozilla.com>, "Tab Atkins Jr." <jackalmage@gmail.com>, Chris Harrelson <chrishtr@google.com>, Simon Fraser <simon.fraser@apple.com>, "public-fx@w3.org" <public-fx@w3.org>, Amelia Bellamy-Royds <amelia.bellamy.royds@gmail.com>, Nexii Malthus <nexiim@gmail.com>
Tab, what do you think about that? What I proposed is more like what 3D
engines do. It would be much better not to treat opacity and other
backdrop-interacting properties as absolutely grouping in a 3D context. And
since all of this is unstable (obviously, which is why I'm writing in the
first place), it can still be modified. 3D can be treated differently,
whereby the grouping effect only applies to the plane of the element that
the backdrop-interacting property is applied to, and does not propagate (by
default) to child elements that have been popped out into separate planes.

This is advantageous because:

   1. Opacity can be applied only to a parent.
   2. End users can propagate opacity to children manually without having
   to modify DOM structure.
   3. Which means it does not break CSS principles.

As for blend modes, it'd be nice to specify a numerical value (amount of
blend), but that can be a later topic. I do feel that what I propose can be
spec'd by simply not requiring opacity (etc) to be absolutely grouping in
all cases. Only 2D content on the plane of the targeted element needs to be
grouped, and 3D popped-out children can be free from flattening.

*/#!/*JoePea

On Tue, Sep 27, 2016 at 11:07 AM, /#!/JoePea <trusktr@gmail.com> wrote:

> Response below (looking for opinions from all).
>
> */#!/*JoePea
>
> On Mon, Sep 26, 2016 at 5:53 PM, Tien-Ren Chen <trchen@chromium.org>
> wrote:
>
>> My two cents is that the web spec should be like laws --- codify what
>> people do and people expect in the real world. Therefore I personally
>> support the proposal "when an element have both
>> transform-style:preserve-3d and opacity other than 1, the opacity
>> value applies to the stacking context subtree in the current plane,
>> and also applies separately to each planes propagated from the
>> descendants."
>>
>> However such proposal is ambiguous when other aspects of the spec is
>> ambiguous. For example, the current spec doesn't define what makes a
>> plane:
>>
>> <style> div { transform-style:preserve-3d; } </style>
>> <div style="opacity:0.5;">
>>     A
>>     <div style="transform:translateZ(0);">B</div>
>>     <div style="position:relative; z-index:0;">C</div>
>> </div>
>>
>> Should be the stacking order equivalent to:
>>
>> <style> div { transform-style:preserve-3d; } </style>
>> <div style="opacity:0.5;">
>>     A
>>     <div style="position:relative; z-index:0;">B</div>
>>     <div style="position:relative; z-index:0;">C</div>
>> </div>
>>
>> Because everything are co-planar, or:
>>
>> <style> div { transform-style:preserve-3d; } </style>
>> <div style="opacity:0.5;">A</div>
>> <div style="opacity:0.5; transform:translateZ(0);">B</div>
>> <div style="opacity:0.5; position:relative; z-index:0">C</div>
>>
>> Because every child stacking context is considered an individual plane,
>> or:
>>
>> <style> div { transform-style:preserve-3d; } </style>
>> <div style="opacity:0.5;">
>>     A
>>     <div style="position:relative; z-index:0">C</div>
>> </div>
>> <div style="opacity:0.5; transform:translateZ(0);">B</div>
>>
>> Because C is considered on the same plane as A?
>>
>> I actually had a lengthy debate with Chris before we shipped the
>> change, and I was convinced that the new spec will introduce least
>> ambiguity understood by vendors and web developers (which is a very
>> desirable property of a spec!).
>
>
> ‚ÄčThis is true!‚Äč However flattening opacity is very undesired. The best
> solution is to spec an alternative (if not legacy-like) behavior before
> shipping these breaking changes (and you know it!).
>
>
>> We are fully aware the spec change
>> won't be backward compatible. However the fact that you complained
>> about the spec change actually reinforced the confidence that we can
>> get away with it, because that implies this area is still actively
>> developed, the contents are alive, and the framework authors will
>> adapt to the change. In other words, we favored simplicity
>
>
> This also means you are also favoring what I believe to be wrong invalid
> behavior when considering the effects from an outer API perspective. For
> someone like me who doesn't always read specs (most people don't have to
> because implementation detail often doesn't matter), for someone like me
> who observes the behavior of the outer web API, this change is simply wrong
> because *applying opacity should not suddenly move your object's
> vertices!*
>
> I hope you can at least agree with me there.
>
> I'd be interested to know if you know of any 3D game engine that does
> opacity flattening on it's 3D objects.
>
> Chrome 53 is following specs, which is a good thing in general, but in
> this case the spec has a flaw. I want all browsers to follow specs, and I
> also want the specs to be correct.
>
> The behavior in Chrome 52 was more desirable.
>
> *However! *Even the "legacy" behavior in Chrome 52 does not allow us to
> apply opacity to a parent without affecting the opacity of the parent's
> descendants. There is no way to do this in the "legacy" implementation
> *or* in the new implementation.
>
> For perspective, the behavior in Three.js scenes is this
> <https://github.com/mrdoob/three.js/issues/9782>: opacity is applied to
> materials, and a material can be applied onto content of a scene graph node
> (Object3D) without the opacity affecting child nodes. Multiplication of
> opacity down the graph would be up to the end user to implement manually.
>
> Thinking along those same lines, and considering that in the "legacy"
> behavior of Chrome 52 we can't opacify a parent without affecting children,
> I believe a better solution to spec would be for opacity to apply to the
> element's paint (it's plane) without flattening it's 3D children, and
> without applying any opacity to the 3D children, where by "3D children" I
> mean any content that has been popped out into a new plane within a 3D
> context.
>
> The rule can be somewhat along the following lines, and backwards
> compatible with the 2D content of the web:
>
>
>    - If transform-style is flat, which is the default for the 2D-based
>    web, then opacity should be a grouping property and will multiply with
>    children of the parent where opacity is applied and all the way down the
>    tree. *This makes sense because the opacity is being applied to a
>    single flat plane which can essentially be considered a plane in 3D space
>    who's texture includes all of the flat content rendered onto it.*
>    - If transform-style is preserve-3d, then opacity does not need to be
>    strictly a grouping property (like Tab Atkins mentions multiple times as
>    the reason that opacity must flatten). In this case, opacity can apply only
>    to the plane that the opacity is applied to, and not any of the 3D children
>    that have been popped out into their own new planes. In effect, opacity
>    would be semi-grouping, and would only affect children that reside on the
>    plane where opacity is applied. In this case Tien, it would be important
>    for us to solve the stacking context problem
>    <https://lists.w3.org/Archives/Public/public-fx/2016JulSep/0071.html> and
>    it would make great sense that any element with `transform:translateZ(0)`
>    should be popped into a new plane in the 3D context, otherwise the plane
>    would momentarily have opacity in the transition from -epsilon to epsilon,
>    and that just doesn't make sense. It should just be a separate 3D object
>    along the continuous spectrum.
>
> It would be really great for something like this to be spec'd for one
> simple reason: it does not break the principles of CSS, because if someone
> wants to propagate opacity down the 3D scene graph, *they can do
> it without modifying the DOM structure (without modifying the HTML markup).*
>
> The new behavior *breaks CSS principles* because the needed workaround
> forces one to modify DOM structure (markup), in order to apply what should
> only be visual styling.
>
> Note, what I am proposing may also apply to any blending properties, not
> just opacity; anything that interacts with backdrop. So flattening would
> not need to occur all the time when 3D is involved. Flattening seems to
> stem from Tab's constant reiteration that the properties are "grouping".
> So, why don't we just make them non-grouping as far as
> 3D-elements-popped-out-into-their-own-plane go?
>
> Additionally, I feel that it would be even better to give developers
> control over the behavior: there could be a new CSS property called
> something like `blend-3d` that would enable/disable arithmetic of blend
> modes (opacity, etc, anything that interacts with a backdrop) down 3D
> elements in a 3D context.
>
> For example:
>
> ```css
> div {
>   blend-3d: auto; /* Defaults to "single" which does not multiply down 3D
> descendant elements in a 3D context. */
> }
>
> div {
>   blend-3d: single; /* does not multiply down 3D descendant elements in a
> 3D context. */
> }
>
> div {
>   blend-3d: multiply; /* multiplies down 3D descendant elements in a 3D
> context, and perhaps it stops at the next 3D descendant element that has
> "blend-3d: single". */
> }
> ```
>
> where by "3D descendant elements" I mean any element that has been popped
> into it's own plane.
>
> What do you all think about something like this?
>
>
>> and
>> unambiguity over convenience on this decision.
>>
>
> Sure, the new spec is less ambiguous (just as unambiguous as saying
> "convert anything with opacity into a circle"), but the new behavior is not
> just slightly less convenient. IT IS A PAIN IN THE ASS.
>
> If you've read about my case (I would be glad to share with you over a
> video call if that helps), the new behavior will cause my library to get
> more *complex and error prone*, consume *twice as much memory* in order
> to render the proper non-nested DOM structure next to my nested
> custom-element DOM structure, and the number-to-string-to-number conversion
> needed in order to pass values to the CSS engine will go from constant
> (with a value of 1) to N where N is the number of descendants inside the
> target element where opacity is being applied which means another *huge
> CPU and Memory cost*.
>
> I'd love to skype with you to show you the problems.
>
>
>>
>> On Mon, Sep 26, 2016 at 5:06 PM, /#!/JoePea <trusktr@gmail.com> wrote:
>> > If you guys are against opacity being applied to descendants of the
>> targeted
>> > element, then maybe, instead of flattening, the opacity should just
>> apply to
>> > the target element's own paint and those descendants that are popped
>> out and
>> > exist in the same 3D space would not be affected by the opacity. Opacity
>> > multiplication would be up to the end developer, and I could live with
>> that.
>> >
>> > But the current behavior is wrong from a 3D perspective. Opacity should
>> not
>> > suddenly and unexpectedly move all the vertices of a 3D object onto a
>> common
>> > plane.
>> >
>> > Please, let's revise the spec, no matter how hard that may be, and
>> let's get
>> > it right.
>> >
>> > - Joe
>> >
>> > /#!/JoePea
>> >
>> > On Fri, Sep 23, 2016 at 12:58 AM, Rik Cabanier <cabanier@gmail.com>
>> wrote:
>> >>
>> >>
>> >>
>> >> On Fri, Sep 23, 2016 at 12:39 AM, Matt Woodrow <mwoodrow@mozilla.com>
>> >> wrote:
>> >>>
>> >>>
>> >>> On 22/09/16 11:37 PM, Rik Cabanier wrote:
>> >>>
>> >>>
>> >>> In addition, your proposal *also* affects web content because opacity
>> is
>> >>> now applied to the group instead of being distributed to the children.
>> >>>
>> >>> It's true, but I figured it would be close enough to the old rendering
>> >>> that the majority of existing content would work with it (assuming
>> they just
>> >>> want opacity, not specifically opacity distributed to the children)
>> while
>> >>> also being correct wrt group-opacity and not implementation dependent.
>> >>>
>> >>>
>> >>>>
>> >>>> This thread was started by an author who's content was broken, so it
>> >>>> seems reasonable to re-visit these assumptions.
>> >>>
>> >>>
>> >>> Yes, we went over his examples and told him how to fix it (= apply
>> >>> opacity to the elements)
>> >>> Since Firefox knows that it's flattening, could it create a warning in
>> >>> the console and point to an MDN page with more information?
>> >>>
>> >>> 1:
>> >>> https://groups.google.com/a/chromium.org/forum/#!msg/blink-d
>> ev/eBIp90_il1o/jrxzMW_4BQAJ
>> >>> 2: https://bugzilla.mozilla.org/show_bug.cgi?id=1250718
>> >>> https://bugzilla.mozilla.org/show_bug.cgi?id=1278021
>> >>> https://bugzilla.mozilla.org/show_bug.cgi?id=1229317
>> >>>
>> >>>
>> >>> I still think that applying group-opacity to a subset of a 3d scene
>> is a
>> >>> reasonable use case (that can't be easily solved without this), and
>> one that
>> >>> we could support without breaking anything worse than we already plan
>> to.
>> >>>
>> >>> Doesn't look like this is getting much traction though, so I'll
>> probably
>> >>> just accept the spec change and go ahead with ship flattening of
>> opacity in
>> >>> Firefox.
>> >>
>> >>
>> >> Good to hear! This was a great discussion.
>> >> If you (or anyone else) can come up with a better solution, maybe we
>> can
>> >> add it to the spec as another value when we integrate Simon Fraser's
>> >> proposal.
>> >
>> >
>>
>
>
Received on Tuesday, 27 September 2016 18:16:52 UTC

This archive was generated by hypermail 2.4.0 : Friday, 17 January 2020 19:49:57 UTC