w3c / csswg-drafts

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

[css-transforms-2] Do 3D transforms contribute to scrollable overflow? #8851

Open dholbert opened 1 year ago

dholbert commented 1 year ago

If an element gets a 3d transform in the Z axis, that makes it visually grow in the x and y dimension, does that contribute to its scrollable overflow in those dimensions?

Here's a testcase, with a 3D-transformed element inside of a scrollable area, using perspective and translate3d. There are three cases, to perform a translate3d(...) translation with a nonzero x, y, and z component, respectively, each of which cause the element to overflow the bounds of its scrollable ancestor. Testcase link: https://bug760753.bmoattachments.org/attachment.cgi?id=9334738

In Firefox, the scrollable ancestor gains scrollbars in all cases, and you can scroll to reach the lime borders on the bottom and right edges of the transformed shape.

In Chromium and WebKit, the first two scrollable areas get scrollbars, but the third does not. You can't scroll to reach the lime border on the bottom or right of the shape in that 3rd case. This implies that those engines aren't treating the (flattened-to-2d-space) Z-axis transform as contributing to scrollable overflow.

Who's correct here? css-transforms-2 doesn't say anything about scrollable overflow that I can find, so I think it needs some clarification.

css-transforms-1 does say a little bit, and it sounds like it's calling for Firefox's behavior, though the text was probably written before 3d transforms existed, so I'm not sure if it's meant to apply to the "flattened-to-screen-pixels" bounds of an element after a z-axis transform. (Nonetheless, it seems reasonable to interpret it as such.) Here's the relevant text there:

[...] transforms can extend (but do not shrink) the size of the overflow area, which is computed as the union of the bounds of the elements before and after the application of transforms

dholbert commented 1 year ago

(CC @dbaron for insights, since he's an editor on this spec, and I think he's been looking at transform-related tests & bugs in recent years.)

dbaron commented 1 year ago

In general I think 3D transforms do contribute to scrollable overflow, and this is pretty interoperable. Based on a very quick look at the testcase I think this is likely the somewhat more particular case, specific to the perspective property, that @mattwoodrow fixed in Mozilla bug 1198135 and that Chromium bug 1264086 agrees is something we should fix.

I'm not sure how well any of this is specified, but I suspect the answer is "not very well".

dholbert commented 1 year ago

Thanks!

(For reference, I ran across this when triaging Mozilla bug 760753 during a pass over a list of old untriaged bugs; that bug seemed to be pointing at this behavioral difference. That bug happens to predate the fix that you referenced in Mozilla bug 1198135, but it's exercising this same behavior regarding perspective and 3D transforms, and likely it was a version of the same issue that just happened to be refined in bug 1198135.)

tabatkins commented 1 year ago

I'm not sure how this is any different from any 2d transform. Both 2d and 3d transforms can move pixels around and expand the visual size of an element; they should be acting identically here. Any divergence is almost certainly a bug.

though the text was probably written before 3d transforms existed

No, 3d transforms were part of the initial Transforms proposal. We eventually split them out for spec maturity reasons, because 3d transforms were dramatically less interoperable than 2d ones were. So anything that predates the split was definitely written with 3d in mind.

mattwoodrow commented 1 year ago

Here's another test case: https://jsfiddle.net/6ha0u2rv/

Looking at that I think the current behaviour is:

WebKit uses the transform to compute overflow area, but just the local transform, not the 'accumulated 3d transform matrix'. As such, the scrollbars are correct for the first example, and wrong the other two.

Blink is similar, except also is trying to account for any perspective (but not preserve-3d). It seems like that's buggy though, since the scrollbars let you scroll further than expected.

Gecko is using the full 'accumulated 3d transform matrix', and all 3 tests case let you scroll to see the full transformed object (and nothing more).

mattwoodrow commented 1 year ago

Mozilla bug 1198135 handled a slightly more complicated version of this, where the 'accumulated 3d transform matrix' includes the scroll offset of an ancestor with overflow:scroll (by setting the perspective property on the scrollable element, and transform on scrolled elements inside).

It's somewhat weird that the scrollable overflow of a scrollable element changes based on scroll position, but I think that's the best outcome for the 'parallax' effect that 3d-transforms+perspective allows.

dbaron commented 1 year ago

I think this is probably a duplicate of #3322.