Re: Proposal: make css clip and clip-path respect containing block

Ah, I slightly misread your email. I thought you were only referring to
clip-path, but you were also referring to the "clip" property. Sorry about
any confusion arising from that.

To restate my main point: I think having scrolled clips on unscrolled
elements is a valuable feature to have, there are real use cases and people
are using clip in the wild for that purpose.

In my last question, about the rewrapping of the opacities, what I should
have been asking was: If the two elements overlap, will they be in the same
opacity group? They should be.

I also have a question about z-order. Not clipping positioned descendants
seems like would make clip-path no longer a stacking context. Would there
be an implicit stacking context *just around* the clip path and the escaped
non-clipped items? Or would the unclipped descendants of the clip-path be
able to freely rearrange their z-order with respect to the clip-path's
siblings?

As for performance, this is not creating any problems for us in Firefox.
That's probably because we always pay the cost of two traversals: First we
traverse the render tree to build the display list, and then we traverse
the display list to build the layer tree. We do not have any intentions of
changing this in the near term.

I'm curious about the cases you mentioned which are not possible to
implement correctly, or which are underdefined. Do you have examples?

Markus

On Mon, Sep 12, 2016 at 9:43 PM, Markus Stange <mstange@themasta.com> wrote:

> This topic is near and dear to my heart, since I've spent the last three
> months of my life laying the necessary groundwork to make this work in
> Firefox with compositing and threaded scrolling.
>
> First off, I'd like to mention that the effect of having a scrolled clip
> on an unscrolled element is not always unexpected. There are pages that
> explicitly want this effect, for example [1], [2], and [3]. These are
> simpler cases though, where the clip is just a rectangle.
> The former two pages achieve this effect using the "clip" property on a
> moving / scrolled element, and nesting a position:fixed element inside that
> element. The latter uses JS to achieve the effect; it moves the clip by
> updating transforms on fixed overflow:hidden elements from a scroll handler.
> The CSS-only variants are obviously preferred because they let the browser
> do correct async scrolling without the help of JS to adjust the effect.
>
> The "clip" property is officially deprecated and superseded by clip-path.
> MDN even says that it has been removed from the specs. I have not verified
> that, but looking at these examples it seems like browsers need to keep
> supporting clip anyway, so maybe it should be re-added. If clip-path will
> not support the above-mentioned scroll effect, but clip does, it would put
> us in an odd situation, and probably cause some confusion for web
> developers.
>
> As for implementation complexity: In Firefox, most of the complexity is
> already required for supporting clip. We don't support clip-path on the
> compositor yet, but we're going to add support for it soon, including
> support for async scrolling. (At the moment, clip-path always forces us to
> use main-thread painting.)
> I don't think our implementation would become noticeable simpler if we
> stopped clipping positioned elements. There's only one case that I'm a bit
> worried about, and that's the case where you have a scroll frame *inside* a
> position:absolute element which is inside a clip-path that is scrolled by a
> different scroll frame. In that case, the two scroll frames would be in
> different branches of the scroll tree, and one of them would move the clip
> of the other scroll frame's contents while the other would move the
> contents themselves. But even that case should be reasonably simple to get
> working.
>
> Not applying the clip to positioned elements would also make other things
> more complicated. The positioned element would need to escape from the
> clip-path container display item (using Gecko terminology here). I don't
> think this kind of escape hatch is used for any other CSS effects.
> I'm also confused about how it work when you add more container effects.
> Let's say you have this structure:
> <div style="clip-path: ...">
>   <div style="opacity: 0.8">
>     <div style="position:absolute;">not clipped</div>
>     <div>clipped</div>
>   </div>
> </div>
> You'll want the opacity to apply to both the clipped and the unclipped
> element here, correct? Will this require individual re-wrapping of the
> escaped items into opacity items?
>
> Markus
>
> [1] http://www.bbc.co.uk/news/resources/idt-248d9ac7-9784-
> 4769-936a-8d3b435857a8
> [2] http://dok.sonntagszeitung.ch/2016/ubsinnovation/
> [3] http://www.flagofplanetearth.com/
>
> On Fri, Sep 9, 2016 at 1:06 PM, Chris Harrelson <chrishtr@google.com>
> wrote:
>
>> TL;DR:
>>
>>  (a) *css clip would no longer clip fixed-position descendants* (these
>> are the only descendants that would not respect containing block because
>> css clip requires absolute position)
>>
>>  (b) *clip-path would no longer clip descendants for whom the element
>> with clip-path is not on the containing block*. e.g. fixed or
>> absolute-position descendants would not be clipped by a clip-path element
>> that is not positioned or is relatively positioned.
>>
>> Details:
>>
>> Compatibility data for Chrome indicates this could be web-compatible. (a)
>> affects fewer than 0.018%
>> <https://www.chromestatus.com/metrics/feature/popularity#ClipCssOfPositionedElement>
>> of pages, and (b) fewer than 0.0069%
>> <https://www.chromestatus.com/metrics/feature/popularity#ClipPathOfPositionedElement>
>> (and this is with -webkit-clip-path). Note that the real numbers may be
>> significantly lower than this, since the counting counts all positioned
>> descendants, not those whose containing block differs.
>>
>> In addition, while -webkit-clip-path is still prefixed in some browsers
>> and not commonly used, we have more opportunity to fix it.
>>
>> Why:
>>
>> 1. Causes confusion for developers. For example:
>>
>>  <div id=scroller style="overflow: scroll">
>>   <div id="clip-path" style="clip-path: ...">
>>     <div id="descendant" style="position: absolute">
>>   </div>
>> </div>
>>
>> "clip-path" will clip "descendant", and is scrolled by "scrolle".
>> "descendant" is not scrolled. Thus as a scroll occurs, the "clip-path"
>> moves relative to "descendant". This is confusing and not really desirable.
>>
>> 2. Causes significant complexity for browsers. Chrome's research shows
>> that there are many bugs
>> <https://docs.google.com/document/d/1LFQ0J_c5RGIJ9g5iOOKQJL96uJZRVUMwQkppyXknI2Y/edit>
>> in the implementation of css clip and clip-path in various special cases
>> of Chrome's implementation and that of other browsers, especially in paths
>> that involve compositing. The bugs are directly due to the weirdness of
>> examples like #1 and even more exotic variants, because implementing it
>> correctly involves carefully separating out pieces of DOM subtrees that
>> need individual compositing and scrolling behavior. This also leads to
>> worse performance due to extra composited layers or tree traversals to
>> determine correct clipping relationships. In some cases it's not even clear
>> it's possible to implement "correctly", i.e. the spec is ill-defined.
>>
>> These bugs and the resulting code complexity are pure overhead that we
>> can get rid of, since as far as I can see, web developers almost certainly
>> don't want these exotic cases to behave "according to the current spec".
>> The proposal in this email doesn't solve everything with containing block,
>> but is a step in the right direction.
>>
>> Thanks,
>> Chris
>>
>
>

Received on Thursday, 15 September 2016 09:40:20 UTC