Skip to content

Conversation

mfreed7
Copy link
Contributor

@mfreed7 mfreed7 commented Jul 25, 2019

With the previous description, opacity was implicitly included in the final set of filters applied to all content. But that's incorrect, at least according to expectation and behavior. Opacity is special here - it needs to be separately applied to the filtered backdrop, because if it is applied only at the end, the fully-opaque contents of B will have already painted over the filtered backdrop. There won't be any show-through of the backdrop, even though the expectation is to see it, given that opacity is less than 1.
While that change is being made, I've also copied the other effects and clips to the backdrop-filtered image as well. These could possibly be defined to only apply once at the end, but the resulting image will be identical or nearly-so, and in practice, the implementation is typically closer to this new definition.

With the previous description, opacity was implicitly included in the final set of filters applied to all content. But that's incorrect, at least according to expectation and behavior. Opacity is special here - it needs to be separately applied to the filtered backdrop, because if it is applied only at the end, the fully-opaque contents of B will have already painted over the filtered backdrop. There won't be any show-through of the backdrop, even though the expectation is to see it, given that opacity is less than 1.
While that change is being made, I've also copied the other effects and clips to the backdrop-filtered image as well. These could possibly be defined to only apply once at the end, but the resulting image will be identical or nearly-so, and in practice, the implementation is typically closer to this new definition.
@mfreed7
Copy link
Contributor Author

mfreed7 commented Jul 25, 2019

@cbrewster Thanks for the suggestions here. Let me know what you think of this draft.
@mstange and @chrishtr Let me know what you think also.

@cbrewster
Copy link

This looks like a good clarification to me; the new steps are much more in line with my work in progress implementation in Firefox. I also agree with the removal of the inverse-transform step which seemed tricky to implement properly in perspective transform cases.

It would also be good to clarify in steps 3 and 7 the order in which transforms, effects, clips, etc, should be applied.

@mstange
Copy link

mstange commented Jul 25, 2019

Huh. This change is the opposite of what my expectations are with respect to opacity. I would expect opacity: 0 to show none of the filtered backdrop, only the unfiltered backdrop.

@mfreed7, here's what you wrote in #53 (comment):

There are several examples where it would make sense for the filtered backdrop to form the starting point for the backdrop-filtered element, so that opacity (and other filters) would apply to that filtered content. One example would be a dialog box that “fades out”.

I very much agree with that sentence, and I'm curious what caused your change of heart.

@cbrewster
Copy link

@mstange with this change, the filtered backdrop would still be invisible if opacity is set to 0. The main difference is that opacity is applied to the filtered backdrop and the element separately and then they are composited together. The current steps state that the filtered backdrop and the contents of the element should be composited together first and then have effects like opacity applied afterwards.

@mstange
Copy link

mstange commented Jul 25, 2019

Oh, I see. That's better, but still not what I would expect. I would expect group opacity, where the filtered backdrop and the element's foreground are part of the same group.

Here's an example: https://codepen.io/mstange/pen/wVzKEW
My element has areas with fully opaque foreground rendering, and also areas where the foreground is transparent. In the transparent areas, the filtered backdrop shows through. If I now fade out that element using opacity, I would not expect the formerly-opaque areas to be tinted by the filtered backdrop - I would only expect them to be tinted by the unfiltered backdrop, because that's what will be left behind once opacity is dialed all the way down to zero.

(Incidentally, the "with-background-color" element in that testcase seems to display an unrelated rendering bug in my Chrome build when I hover it and the animation stops...)

@mfreed7
Copy link
Contributor Author

mfreed7 commented Jul 29, 2019

@mstange I see the point you're making here, that in some cases it's confusing that a partial region of your element that is fully-opaque shows through the backdrop-filtered effect when opacity is applied. However, I would submit that the more common case, which would also cause confusion if this were implemented the other way, is for the entire background to be an opaque color, with opacity<1 applied to "see through" it to the filtered backdrop. In that case, people will not be able to see any of the backdrop-filtered content. Seems like the lesser of two evils. The core issue is that the backdrop-filtered content lives somewhere in between the element and the backdrop.

@cbrewster Thanks for the comments. I'll see what I can do about clarifying the order of transform, effect, clip. If you have particular suggestions for that, let me know!

@mstange
Copy link

mstange commented Jul 29, 2019

However, I would submit that the more common case, which would also cause confusion if this were implemented the other way, is for the entire background to be an opaque color, with opacity<1 applied to "see through" it to the filtered backdrop.

I see. I don't know if that'll be the more common case, as it's also incompatible with Safari's current implementation. In Safari you can't see the filtered backdrop if you use opacity on opaque foreground.

@mfreed7
Copy link
Contributor Author

mfreed7 commented Aug 5, 2019

@mstange, hmm, you're right about Safari's current behavior. Opaque layers (even with opacity) do not show the backdrop. I don't know why, but this just feels weird to me. Putting opacity on an element should let you see through that element. Putting backdrop-filter on an element should paint a filtered copy of the backdrop behind it. Putting these two together, backdrop-filter with opacity should let you see the filtered backdrop. (Of course, I see how it could be defined that way, I'm just saying I'm not sure which way is more intuitive for developers.)

I'm not sticking to this position very strongly, but I would like to get it resolved one way or the other soon. I'm not sure which causes more compat issues at this point - changing Chrome to match Safari here, or leaving it as is and making sure the spec is right. But the sooner this is nailed down, the better.

@hober
Copy link
Member

hober commented Aug 9, 2019

cc @grorg @smfr

@mstange
Copy link

mstange commented Aug 11, 2019

I still prefer the approach where the element rendering and the filtered backdrop are part of the same opacity group. My justification at this point is mostly Safari compat. Arguing via intuition / what feels right doesn't seem fruitful because there seem to be at least two different intuitions and we don't know which one is shared by the majority of authors, or if there even is such a thing as a shared intuition among authors about this behavior.

Actually, scratch that, I will try to justify my intuition one more time: I expect fractional opacity values to interpolate between the rendering at opacity:0 and the rendering at opacity:1. If the element foreground is opaque, the filtered backdrop isn't visible at either 0 or 1. So as I modulate my opacity value between those two extremes, I don't expect the filtered backdrop to become partially visible for in-between values.
Furthermore, setting opacity on a given DOM element has always acted as opacity on a single "effect node". The only case that I'm aware of where opacity on a single DOM element operates on multiple effect nodes independently is preserve-3d rendering where opacity gets propagated into the leaf layers. But I think that particular behavior is regarded as an unfortunate exception that was the lesser of two evils.

@mfreed7
Copy link
Contributor Author

mfreed7 commented Aug 19, 2019

@mstange, I can see your point about Safari compat. However, there is already a bigger compat issue there, w.r.t. the Backdrop Root concept, so I'm not sure the nuances of opacity are as important here. Though clearly we should try to get all of this right, as much as there is a "right".

And I can understand your intuition about expecting fractional opacity to interpolate. But I would disagree about which parts of the behavior matter more for intuition. Your point is that while animating between two opacity values, there could be a tinge of partially filtered content visible. Perhaps I'm wrong, but that seems like a very subtle difference. My concern is that there will be confusion about why the effect isn't working at all, when opacity is used. Or there will be confusion about why a background with animated alpha behaves differently from animated opacity on the element. See, e.g., the description given on the MDN page for backdrop-filter, or our recent blog post on the feature. Both refer to either making the background transparent, or making the element transparent (with opacity) to "see through" it to the backdrop-filtered content. This seems to indicate that the "default" intuition is that backdrop-filter modifies/filters the "backdrop" of the element, not the element itself. I.e. you're looking through the element to see the backdrop-filtered content behind it. So you just need to make the element transparent somehow, to see through it. Breaking this symmetry between background alpha and element opacity seems not great. I will definitely concede that the metaphor is imperfect already, as filters and opacity applied to the element also affect the backdrop-filtered content. But I think the points above about the transparency intuition still hold.

As for effect nodes, I think that is implementation dependent. The Chromium implementation still has a single effect node for opacity in this case. In the case of an element with both opacity and backdrop-filter, there will still be only a single effect node, containing both the backdrop-filter list and the opacity value. The filtered backdrop content is drawn as a separate intermediate step after rendering the element's content, and before compositing it into the backdrop surface.

Base automatically changed from master to main February 2, 2021 19:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants