Absolute Positioned Floating Header Jitters in Safari

前端 未结 6 821
刺人心
刺人心 2020-12-31 02:52

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

相关标签:
6条回答
  • 2020-12-31 03:08

    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.

    0 讨论(0)
  • 2020-12-31 03:12

    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...

    0 讨论(0)
  • 2020-12-31 03:25

    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.

    0 讨论(0)
  • 2020-12-31 03:26

    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.

    0 讨论(0)
  • 2020-12-31 03:28

    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;
    }
    
    0 讨论(0)
  • 2020-12-31 03:30

    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;

    0 讨论(0)
提交回复
热议问题