[Positioner] Not all `sticky` and `positionMethod` combos make sense
- Dominant language
- TypeScript
- Stars
- 10.9k
- Forks
- 543
- Avg merge
- 1d 20h
- Merged PRs (30d)
- 101
Description
Finally got to test `sticky` and `positionMethod` options thoroughly:
https://p8xtr7.csb.app/
https://codesandbox.io/p/sandbox/postion-method-sticky-combos-p8xtr7
Testing in Safari on a M1 Pro device:
| Props | static container | fixed container |
| ---------------------------------------- | ---------------- | --------------- |
| positionMethod="absolute" sticky={false} | Perfect | Skips frames badly |
| positionMethod="absolute" sticky={true} | Skips frames badly | Skips frames badly |
| positionMethod="fixed" sticky={false} | Skips frames mildly | Perfect* |
| positionMethod="fixed" sticky={true} | Skips frames mildly | Perfect* |
\* Note: in fixed containers, `sticky` value has no effect
https://github.com/user-attachments/assets/b3ad8d68-086c-48bf-9791-9db4d816b0aa
Chrome is better, as it skips fewer frames (but exactly in the same ways).
Firefox is similar/worse.
Effectively, there seems to be two combinations that make sense:
- positionMethod="absolute" sticky={false}
- Works great in a static container
- positionMethod="fixed" sticky={true}
- Works great in a fixed container
- Works OK in a static container to achieve a sticky positioner
Am I missing the use cases for the rest?
- positionMethod="fixed" sticky={false}
- In static containers: just like `positionMethod="absolute" sticky={false}`, but worse because it can skip frames
- In fixed containers: exactly like `positionMethod="fixed" sticky={true}`
- positionMethod="absolute" sticky={true}
- In static containers: skips frames when running up the edge
- In fixed containers: skips frames all the time
If not missing any use cases, it looks like this API can be reduced to a single boolean prop or a single string prop with two values.
***
One more thing to consider is that it might be viable to implement a different positioning strategy for a better sticky popup experience in a static container: use position absolute while the element is attached to the trigger and switch to position fixed when it attaches to the edge of the viewport. This way, the only opportunity to skip frames would be during the position change, and not during the rest of the scroll events.
Contributor guide
Assessment
This issue has not been assessed yet.