I have a simple JSFiddle of a single floating header here:
http://jsfiddle.net/zT9KQ/
Basically, this uses translate3d
to kick in the GPU and hardware accelerate the floating header so that it may be drawn more smoothly. The header jitters in the latest Safari but gets drawn perfectly fine in the latest Chrome, FF and Opera. The actual code that is being affected by this (the code that spurred this question) is code I've written that cannot be shared publicly but works in a similar manner where fixed
positioning is, unfortunately, not a valid solution.
I have tried:
- Setting the
backface-visibility
CSS property tonone
. - Setting the
perspective
CSS property to1000
. - Playing with
requestAnimationFrame
during the animation logic. - Throttling the scroll event callback.
- Setting the
translateZ
transform to something higher than0px
.
But none of this has worked (or at least - it seems reasonable to assume the GPU has kicked in but the jittering persists). I noticed that two questions are already open that are identical this one I'm raising but no one has answered them:
- Jitter in Sticky Header in Safari
- Implementing fixed position in javascript causes jitter in Safari when scrolling
Is this a known bug? Is there a performance hole I'm not sealing up?
EDIT
I have been receiving a lot of questions as to why position: fixed
is not a valid option. To directly reply to Antony's comment on the question itself:
I'm not emulating/reinventing position: fixed
. If you look at the top-voted answer (as of this comment), you will see that this seems to be a Safari issue. The reason position: fixed
is undesirable in this case is because the code in question must be able to support multiple floating headers that sit below each other and have a "container" range where there may be infinitely nested containers. Using fixed positioning not only makes the code more complicated in the case where these floating headers live in a container that horizontally scrolls but also makes the component more brittle overall (calculating offsets when the widget needs to sit within another container somewhere else on the page). So, semantically, absolute
positioning fits my needs better than fixed
.
SECOND EDIT
Upon thinking about what Antony had been telling me (that I may be reinventing the wheel), and after hearing about -wekbit-sticky
from user3716477, I would like to update the question to show what I'm trying to do. You can see how my code behaves in every browser other than Safari here:
http://cl.ly/3y1i3C473G2G
I have learned:
- You cannot rely on the
scroll
or really any scroll-like events (such asmousewheel
) since they are asynchronous in nature. I submitted a bug to Apple detailing what was happening and they closed the bug for this reason. - There is no real way to do what I want as of now - to have multiple floating headers that stack and replace each other. I guess I'll have to wait for something like
-webkit-sticky
to come out. - I should include all relevant information in SO questions from here on out. :-P
Thanks for playing guys! Here's the exact response I received from Apple:
Apple Developer Relations09-Jun-2014 01:16 PM
Engineering has determined that there are no plans to address this based on the following:
Code is using scroll events, which are asynchronous.
We are now closing this bug report.
If you have questions regarding the resolution of this issue, please update your bug report with that information.
Please be sure to regularly check new Apple releases for any updates that might affect this issue.