position: sticky
是定位元素的新方法,在概念上与 position: fixed
类似。不同之处在于,具有 position: sticky
的元素在其父项中的行为类似于 position: relative
,直到在视口中达到指定的偏移阈值为止。
用例
转述了 Edward O’Connor 最初关于此功能的提议:
粘性定位简介
只需添加 position: sticky
(带有供应商前缀),我们就可以告知某个元素处于 position: relative
状态,直到用户滚动相应项(或其父项)到距离顶部 15px 的位置:
.sticky {
position: -webkit-sticky;
position: -moz-sticky;
position: -ms-sticky;
position: -o-sticky;
top: 15px;
}
在 top: 15px
,该元素会变为固定状态。
为了在实际场景中说明此功能,我制作了一个演示,它会在您滚动页面时固定博客标题。
旧方法:滚动事件
到目前为止,为了实现粘性效果,网站需要在 JS 中设置 scroll
事件监听器。实际上,我们在 html5rocks 教程中也使用了这种方法。在小于 1200 像素的屏幕上,目录边栏会在滚动一定量后变为 position: fixed
。
下面的代码(现在是老式)让标题在用户向下滚动时固定在视口顶部,当用户向上滚动时固定在视口顶部:
<div class="header"></div>
<script>
var header = document.querySelector('.header');
var origOffsetY = header.offsetTop;
function onScroll(e) {
window.scrollY >= origOffsetY ? header.classList.add('sticky') :
header.classList.remove('sticky');
}
document.addEventListener('scroll', onScroll);
</script>
不妨试试:http://output.jsbin.com/omanut/2/
这很简单,但是如果您想针对一群 DOM 节点(例如,在用户滚动页面时,博客的每个 <h1>
标题)都执行此操作,那么这个模型会快速分解。
为什么 JS 不理想
一般来说,使用滚动处理程序不是一个好主意。用户往往会处理太多工作,并且想知道为什么他们的界面会卡顿。
需要考虑的另一个因素是,越来越多的浏览器正在实现硬件加速滚动,以提升性能。这样做的问题在于,当 JS 滚动处理程序运行时,浏览器可能会回退到较慢的(软件)模式。现在,我们不再在 GPU 上运行。现在,我们返回到 CPU 上。效果如何呢?用户在滚动页面时会觉察到更多卡顿。
因此,在 CSS 中让此类特征具有声明式意义非常合理。
支持
抱歉,这个问题没有规范。早在 6 月份,它就在 www 样式上提出了,之后刚刚发布在 WebKit 中。这意味着没有合适的文档可供参考。不过,有一点需要注意,根据此 bug,如果同时指定了 left
和 right
,则 left
胜出。同样,如果同时使用 top
和 bottom
,系统会优先使用 top
。
当前支持 Chrome 23.0.1247.0 及更高版本(现行 Canary 版)和 WebKit 每夜版。