w3c / fxtf-drafts

Mirror of https://hg.fxtf.org/drafts
https://drafts.fxtf.org/
Other
69 stars 49 forks source link

[filter-effects-2] User feedback: backdrop-filter is way less useful because it requires children to not escape the "backdrop rectangle" #408

Open ell1e opened 4 years ago

ell1e commented 4 years ago

Okay, so I just played around with backdrop-filter and at first it was really cool: I can have a modern milk glass effect with stuff blurred behind, and it "just works"?? How cool is that?

But then I discovered the inconvenient weirdness of its layout effect: backdrop-filter apparently requires all child elements to be contained and therefore messes up all absolute/fixed/relative children that previously escaped their milk glass background parent, and contains them inside. While you might argue that this is not an issue since I can just move affected child elements out of their parent, this feels like a huge limitation for websites designed to have clean DOM like this:

<html lang="en">
<head>...</head>
<body>
    <content>
        <img id="main-logo-small" src="/examplelogo.png" alt="Horse64 Logo"/>
        <h1>example, simple and versatile.</h1>
        <p><a href="/download">Try <em>Example</em> now</a>, a high-level language ...

scr (the white round corner content box with the main text inside is <content>, and as you can see, the <h1> heading is clearly placed outside of it)

The problem here, if it isn't obvious, is that it's IMHO a very useful trick to be able to move children outside their parent in layouting to "loosen" the strict what-contains-what relationship, and therefore avoid unnecessary clutter in the DOM with tons of separate containers just for visual layouting when on a semantic level they really aren't desired to be there.

backdrop-filter breaks this, apparently to get some sort of nice contained "backdrop rectangle" with all children inside which would be ruined by letting them escape like that, so it doesn't seem to be allowed.

I don't know why exactly this decision was made, but as seen with the example above this can be a problem. And why I don't get it as a user is, background transparency doesn't have this issue, and backdrop-filter effects similarly only seem to interact with what is behind the element, but not actually the backdrop itself much - e.g. the blur doesn't blur the element itself into its background, rather just what is behind it. So why does it even need to be tied to a neatly contained backdrop like that? Why can't it just let all children be wherever, and similarly to background transparency it just applies to the clear bounds of the parent and if any children escape then just ignore the parts of the child that are outside the bounds for the effect? The way it is done right now seems really limiting from a layouting perspective, and a bit disappointing with how it clashes with things. It's frustrating to need to pick between a semantically clean DOM, and actually having it look like I want it to.

I just wanted to give you this feedback hoping it could be changed. Maybe that is not technically feasible, I don't know. But I sure wish it was how it was done instead.

Or is there a workaround for this that doesn't involve cluttering the DOM I'm not aware of? I really can't think of any

mfreed7 commented 3 years ago

Thanks for the comment. If I understand your point, it is that the children ("C") of the element ("B") with backdrop-filter applied can be positioned outside the bounds of B, e.g. with absolute positioning. And then in that case, the backdrop behind C isn't backdrop-filtered. Is that right?

If that's the issue, this is actually mostly for convenience to the author. The alternative is to filter absolutely everything on the page that lives below the z-index of B, and that would often not be what the author is intending. Typical examples for backdrop filter are menu bars (that blur the content as it scrolls under) and dialog boxes (that blur the contents behind the dialog). If you're looking for a way to filter absolutely everything on the page, it is easier to do something like <style> html {filter: blur(5px)} </style>. I.e. just filter everything.

I don't know of a great workaround for what you're trying to accomplish, other than making the C elements siblings, instead of children, of B, and apply backdrop-filter to C also. Would that not work?

ell1e commented 3 years ago

And then in that case, the backdrop behind C isn't backdrop-filtered. Is that right?

No, I was unclear. The problem is that C's positioning is completely messed up (by spec, because it limits children to the area of a backdrop'ed parent, and makes the parent a position:relative item that will automatically be e.g. a fix point for all absolute children even if I don't want that at all). For the above code example, C is <h1> and B is <content>. You can see that the heading lives outside the rounded border box purely for design reasons, while semantically it belongs to the content area. This appears to be fundamentally incompatible with how backdrop-filter works right now, which I don't like.

I don't know of a great workaround for what you're trying to accomplish, other than making the C elements siblings, instead of children, of B, and apply backdrop-filter to C also. Would that not work?

This messes up the markup. You can see this in the code example I gave above, I would be forced to move the <h1> outside of the <content> tag. This is bad for any semantic reading of it, therefore I think this backdrop restriction is unreasonable. There are ways around it by introducing more containers just for the styling, but those again semantically are just noise that shouldn't be there.

I don't think C should be backdrop-filtered at all if outside of B, so this wouldn't affect the extents of B's filtering in any way. This is just about the odd layouting restrictions that come with it, seemingly to make the technical implementation on the browser engine side easier(?). But I find it quite gets in the way of styling the page as intended.

If that's the issue, this is actually mostly for convenience to the author

I really can't see any convenience in it personally, my reactions were surprise, then disbelief, then being annoyed :woman_shrugging: but maybe that is just me. However, I do understand it might possibly be beneficial for the browser engine makers.

SebastianZ commented 3 years ago

Without a live example and reference to the specification, it took me quite some time to find out what the issue actually is. As I understand it, @ell1e refers to this sentence in the "Filtering and Clipping" section:

A computed value of other than none results in the creation of both a stacking context [CSS21] and a Containing Block for absolute and fixed position descendants, unless the element it applies to is a document root element in the current browsing context.

So in https://jsfiddle.net/SebastianZ/jp5ts2mv/ the "Headline" text is positioned differently when backdrop-filter is applied. If it is defined, <section> becomes a containing block and the <h1> is positioned relatively to it, without it, the <h1> is positioned absolutely.

To authors this is an unexpected and undesired behavior. And it's unclear why this behavior is copied over from the filter property. For the filter property it might still be clear because it applies the filters to the element itself, though backdrop-filter filters what's behind the element, so this shouldn't have an effect on the layout of the element's children.

Sebastian

ell1e commented 3 years ago

To authors this is an unexpected and undesired behavior. And it's unclear why this behavior is copied over from the filter property. For the filter property it might still be clear because it applies the filters to the element itself, though backdrop-filter filters what's behind the element, so this shouldn't have an effect on the layout of the element's children.

Yes, exactly. Thanks for the very nice summary. And for something that just applies to the background, this has IMHO quite severe and undesirable layout limitation implications. Basically, it makes many tricks to keep the HTML markup simple and semantically meaningful impossible, most importantly the "move child outside of parent via position absolute" trick that can be very helpful for something that is semantically best kept as a child, but may visually actually float outside of the parent.

Is there a chance this will ever be revised?

mfreed7 commented 3 years ago

As I understand it, @ell1e refers to this sentence in the "Filtering and Clipping" section:

A computed value of other than none results in the creation of both a stacking context [CSS21] and a Containing Block for absolute and fixed position descendants, unless the element it applies to is a document root element in the current browsing context.

So in https://jsfiddle.net/SebastianZ/jp5ts2mv/ the "Headline" text is positioned differently when backdrop-filter is applied. If it is defined, <section> becomes a containing block and the <h1> is positioned relatively to it, without it, the <h1> is positioned absolutely.

To authors this is an unexpected and undesired behavior. And it's unclear why this behavior is copied over from the filter property. For the filter property it might still be clear because it applies the filters to the element itself, though backdrop-filter filters what's behind the element, so this shouldn't have an effect on the layout of the element's children.

Ahh, I see, the question is about the forced containing block. That is there for the same reasons as for filter, and it is more fundamental than just implementation convenience. @chrishtr can probably explain more succinctly than I can.