position: sticky
是一种定位元素的新方法,在概念上与 position: fixed
类似。区别在于,具有 position: sticky
的元素在其父级中会像 position: relative
一样运行,直到视口中满足给定的偏移量阈值为止。
使用场景
以下内容摘自 Edward O’Connor 最初提出此功能的提案:
粘性定位简介
只需添加 position: sticky
(供应商前缀)即可指示元素为 position: relative
,直到用户将项(或其父项)滚动到距离顶部 15 像素的位置:
.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-style 中提出,刚刚发布在 WebKit 中。也就是说,没有可供参考的详细文档。不过,需要注意的是,根据此 bug,如果同时指定了 left
和 right
,则 left
优先。同样,如果同时使用 top
和 bottom
,则 top
优先。
目前支持 Chrome 23.0.1247.0 及更高版本(当前 Canary 版)和 WebKit 每夜 build。