w3c / csswg-drafts

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

[css-position] Sticky positioning with transform between it and reference box #3186

Open Loirooriol opened 6 years ago

Loirooriol commented 6 years ago

CSS Transforms can distort elements a lot. However, this wasn't a big problem for top, left, bottom and right properties, because transformed elements generate a containing block for all descendants.

However, sticky positioning is special because the insets are not calculated with respect to the containing block, but an scrollable ancestor instead. https://drafts.csswg.org/css-position/#sticky-position

This can make things unintuitive, sticking the untransformed element to an edge of the ancestor may not look like stickment at all after the transform.

http://jsfiddle.net/ns68kdxt/ ```html
Scroll
Transform
Sticky
``` ```css #scroll{ overflow-y: scroll; height: 100px; border: 3px solid; margin-top: 50px; } #scroll::after { content: ''; display: block; height: 400px; } #transform { transform: translateX(200px) rotate(90deg); transform-origin: 0% 0%; background: #ff0; height: 200px; top: 0; left: 100px; border: 3px solid; } #sticky { position: sticky; top: 0; background: #0ff; border: 3px solid; } ```

Scrolling down moves the sticky element from right to left smoothly in Chromium. Seems OK but unintuitive. It moves discretely and buggy in Firefox. Should sticky positioning still work in this case? What about similar cases like `contain: strict`, should scrolling an element outside the containment affect a sticky element inside the containment?
upsuper commented 6 years ago

This looks like a bug in Gecko... Probably some edge case which was not considered for sticky. Have you filed the bug to Gecko?

jonjohnjohnson commented 6 years ago

@upsuper I've filed a few issues against position:sticky for gecko and most seem to be *fixed by the current work on WebRender (https://bugzilla.mozilla.org/show_bug.cgi?id=1456938) and the test case provided above in current firefox nightly (64.0a1 (2018-10-07) (64-bit)) with WebRender enabled shows sticky position moving continuously, just like chromium.

jonjohnjohnson commented 6 years ago

@Loirooriol

Should sticky positioning still work in this case?

In light of at least ios safari using position:sticky as a mechanism to afford perspective/transform values an affect, creating some new scrolling texture, as unintuitive as it is, I think transform values between the "reference box" and the element should continue to have scrolling effects so that rich, but lean runtime, UIs can be achieved both like your sideways scrolling example above as well as what the chromium team describes here... https://developers.google.com/web/updates/2017/03/custom-scrollbar#what_about_ios

jonjohnjohnson commented 5 years ago

@upsuper the original test case provided by @Loirooriol no longer moves "discretely and buggy" in the latest firefox nightly.

But if perspective is not set to it's initial value of none for the transformation, the bug returns in gecko.

http://jsfiddle.net/gmwnLqkj/

Should I file an issue for this? Or wait until the csswg weighs in?

Loirooriol commented 5 years ago

I still see the problem in latest nightly, filed https://bugzilla.mozilla.org/show_bug.cgi?id=1519073

tabatkins commented 4 years ago

Okay, so Chrome is behaving as intended. It's a little wacky, but layout (including stickypos) happens before transforms do, so yeah, scrolling should shift the sticky element sideways in this case.

Firefox's behavior is just a quality-of-implementation issue.

Do you think we should include this in an example or a note somehow, or just leave it as a fun easter egg for people to stumble across?

Loirooriol commented 4 years ago

Probably an example is not needed, but it could be useful to note that a sticky box may end up being painted outside of the sticky view rectangle (even if the intersection with the containing block is not empty) because of transforms, or something like that.

hejtmii commented 4 years ago

Hi, I am one of the guys who just found the easter egg (I guess).

My scenario is sticky positioning relatively to the scrolling container other than the body using a specific nested combination of positioning.

https://jsfiddle.net/martinh_kentico/wbybegxy/11/

But when you uncomment transform: translateY(200px); in CSS (which applies to one of the parents between the scrolling container and the sticky combo), the sticky positioning gets totally busted by that.

Is it the same problem you are discussing above?

Can it be fixed somehow while maintaining the transform? (we need it to properly position the overlay in which the editor is placed)