1.特性

  • position:relative和position:fixed的混合,在未滑到指定位置的时候表现为relative,滑到后表现为fixed
  • 举个栗子https://codepen.io/wutw/pen/RmzybE

2.注意

  1. 父级元素不能有任何overflow:visible以外的overflow设置,否则没有粘滞效果。因为改变了滚动容器(即使没有出现滚动条)。因此,如果你的position:sticky无效,看看是不是某一个祖先元素设置了overflow:hidden,移除之即可。
  2. 父级元素也不能设置固定的height高度值,否则也没有粘滞效果。
  3. 同一个父容器中的sticky元素,如果定位值相等,则会重叠;如果属于不同父元素,则会鸠占鹊巢,挤开原来的元素,形成依次占位的效果。
  4. sticky定位,不仅可以设置top,基于滚动容器上边缘定位;还可以设置bottom,也就是相对底部粘滞。如果是水平滚动,也可以设置left和right值。
  5. sticky元素仅在其父元素内生效

3.优点

对于兼容的页面,省去一大段js代码,页面顺滑不卡顿

4.缺点

看看这兼容性就会哭

5.Hack

对此兼容性,需采用hack确保万无一失

<div class='top'>
    top
</div>
<div id='root' style=' position: -webkit-sticky;
    position: sticky;
    top:0;
    background:red'>
我是sticky
</div>
function pageScroll() {
    const scrollTop = (document.documentElement.scrollTop || 0) + (document.body.scrollTop || 0);
    const topHeight = $('.top').height();
    const $root = $('#root');
    if (scrollTop > topHeight) {
      $('#root').css({position: 'fixed',top:'0'});
    } else{
     $('#root').css({position: 'relative',top:'auto'});
    }
  }

function bindPageScroll() {
    // judge brower support `position: sticky` or not
    const position = $('#root').css('position');
    if (position === 'sticky' || position === '-webkit-sticky') {
      $('#root').css('top', 0);
    } else {
        //不支持sticky,hack方法
      const $doc = $(document);
      $doc.on('scroll', () => {
        this.pageScroll();
      });
      $doc.on('touchmove', () => {
        this.pageScroll();
      });
    }
  }

6.参考

https://www.zhangxinxu.com/wordpress/2018/12/css-position-sticky/ 张鑫旭大神说的真好


凡心所向,素履所往