关于CSS吸顶效果position:sticky的使用

文章2020-03-091,150 人已阅来源:网络

通常的js解决方案

为了实现这种粘性布局我们一般都是通过js监听windowscroll事件,当需要固定的元素滚动到窗口顶部时,把元素的position属性设置为fixed,否则,取消fixed,简单的js代码如下:

$(window).scroll(function () {
      var top = $(window).scrollTop();
  if (top >= nav_top) {
       $(".nav_box").addClass('nav_box_top');
  }else{
       $(".nav_box").removeClass('nav_box_top');
  }
 });

上面这种方法在chrome模拟手机浏览器的表现很好,但是在移动端浏览器上粘顶的效果就没有那么平滑,尤其是在ios设备上,ios下的浏览器会在页面滚动的时候,暂停所有js的执行,直到滚动停止才会继续去执行js(注意暂停了所有js的执行,所以考虑用setTimeoutsetInterval也是没有用的)。所以页面滚动时,scroll事件在iOS的浏览器下并不会持续被触发,而是在页面滚动停止后,才会去触发一次scroll事件。

使用position:sticky

当然,使用css更丝滑。

.sticky_box{
     position:relative 
}
.sticky{
     position: sticky;
     top:0;
     z-index: 100;
 }

position:sticky的表现上像是position:fixedposition:relative的结合体,设置了position:sticky的元素,特征如下:

  1. 元素不会脱离文档流,并保留元素在文档流中占位的大小
  2. 元素在容器中被滚动超过指定的偏移值时,元素在容器内固定在指定位置
  3. 元素固定的相对偏移是相对于离它最近的具有滚动框的祖先元素,如果祖先元素都不可以滚动,那么是相对于viewport来计算元素的偏移量

使用注意事项

  1. 不能有任何祖先元素设置overflow:hidden,否则没有粘滞效果。因为改变了滚动容器(即使没有出现滚动条)
  2. sticky元素的父元素已不再完整占据sticky元素的固定区域时,sticky元素不再固定,因此:
    • 父级元素的height必须超过sticky元素的height,这样在height范围内有粘滞效果。
    • 同一个父容器中的sticky元素,如果定位值相等,则会重叠;如果属于不同父元素,则会随着父元素不再完整占据sticky元素的固定区域以后,再由其他父元素的sticky子元素占据固定位置
  3. sticky定位,不仅可以设置top,基于滚动容器上边缘定位;还可以设置bottom,也就是相对底部粘滞。如果是水平滚动,也可以设置leftright值。

浏览器兼容性检测

如果有必要,还可以去检测浏览器是否支持sticky属性,从而决定是使用js监听事件去实现还是通过原生CSS去实现,检测代码如下:

var isSupportSticky = function() {
     for (var t = ["", "-webkit-", "-ms-", "-moz-", "-o-"], e = "", n = 0; n < t.length; n++)
         e += "position:" + t[n] + "sticky;";
     var i = document.createElement("div"),
         a = document.body;
     i.style.cssText = "display:none;" + e,
         a.appendChild(i);
     var r = /sticky/i.test(window.getComputedStyle(i).position);
     return a.removeChild(i),
         i = null,
         r
 }