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 ha
You could try and disable all and any javascript-ish scroll handling and just simply remove
position: relative;
from the .container
.
Afterwards just add h1{ top:0; }
and it will happily stick to the .scroll-container
.
Excerpt from CSS absolute positioning:
Position it at a specified position relative to its closest positioned ancestor...
To explain - your absolute H1 will look up the tree for the first ancestor element which defines a "position" property and inherit it as a 0,0 reference point.
It could be a WTF at first, but this behaviour is a powerhouse once you tame it.
EDIT: Related to the original jsFiddle, I made some more property removals:
http://jsfiddle.net/253Ss/
^ .container
wrapper could be removed as well, since it is no more neccessary in a technical sense.
If you are using something similar to the jiddle code you have to check if browser is safari and then make it a different way like:
$(function () {
var $header = $('h1'),
$container = $('.container'),
$scrollContainer = $('.scroll-container'),
scrollContainerOffset = $scrollContainer.offset().top;
$scrollContainer.on('scroll', function () {
var top = Math.max(0, $container.offset().top * -1 + scrollContainerOffset);
$header.css('top', top + 'px');
});
});
Even when it isn't the way you want your problem to be solved, it might be a workaround that may help...
It appears to be a bug with Safari scrolling. If you drag the scrollbar manually (don't use the trackpad gesture to scroll), then there is no jittering.
Chrome (and other browsers) handle scrolling differently which is why this bug is only present on Safari. You might want to submit a bug report to Apple.
Since there is an apparent delay between scrolling with the trackpad and the scroll
event firing, you can attach the handler to an additional mousewheel event to smoothen things up.
$scrollContainer.on('scroll mousewheel', function () {
// reinvent the wheel here
});
You can see in this demo here that jittering is far less likely to occur when you scroll with the trackpad. In the demo, I have invoked the handler on load to eliminate the flash when you first scroll on Safari. There may still be some occasional jitter, but if you want to minimize that, you can go the resource intensive way of using setInterval and requestAnimationFrame.
This might fix the problem for now, but as I have said before, this emulation approach is not ideal and you are very likely to run into more trouble down the road.
How about a little restructuring, like this: http://jsfiddle.net/me2loveit2/zT9KQ/6/
html:
<div>
<h1>Header</h1>
<div class="container">
<div class="content"></div>
</div>
</div>
CSS:
.container {
height: 300px;
position: relative;
overflow-y:scroll;
}
.content {
height:1000px;
}
h1 {
position: relative;
top:0px;
left:0px;
margin: 0;
width: 100%;
background: black;
color: white;
}
Scroll events are sent asynchronously in various browsers; you should not rely on them to do things like this.
The best solution would be to use position:-webkit-sticky; top: 0;