关于CSS吸顶效果position:sticky的使用
通常的js解决方案
为了实现这种粘性布局我们一般都是通过js监听window
的scroll
事件,当需要固定的元素滚动到窗口顶部时,把元素的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的执行,所以考虑用setTimeout
或setInterval
也是没有用的)。所以页面滚动时,scroll
事件在iOS的浏览器下并不会持续被触发,而是在页面滚动停止后,才会去触发一次scroll
事件。
使用position:sticky
当然,使用css
更丝滑。
.sticky_box{ position:relative } .sticky{ position: sticky; top:0; z-index: 100; }
position:sticky
的表现上像是position:fixed
和position:relative
的结合体,设置了position:sticky
的元素,特征如下:
- 元素不会脱离文档流,并保留元素在文档流中占位的大小
- 元素在容器中被滚动超过指定的偏移值时,元素在容器内固定在指定位置
- 元素固定的相对偏移是相对于离它最近的具有滚动框的祖先元素,如果祖先元素都不可以滚动,那么是相对于
viewport
来计算元素的偏移量
使用注意事项
- 不能有任何祖先元素设置
overflow:hidden
,否则没有粘滞效果。因为改变了滚动容器(即使没有出现滚动条) - 当
sticky
元素的父元素已不再完整占据sticky
元素的固定区域时,sticky
元素不再固定,因此:- 父级元素的
height
必须超过sticky
元素的height
,这样在height范围内有粘滞效果。 - 同一个父容器中的
sticky
元素,如果定位值相等,则会重叠;如果属于不同父元素,则会随着父元素不再完整占据sticky
元素的固定区域以后,再由其他父元素的sticky
子元素占据固定位置
- 父级元素的
sticky
定位,不仅可以设置top
,基于滚动容器上边缘定位;还可以设置bottom
,也就是相对底部粘滞。如果是水平滚动,也可以设置left
和right
值。
浏览器兼容性检测
如果有必要,还可以去检测浏览器是否支持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 }