坚持您的着陆!位置 - 在 WebKit 中粘性着陆

Eric Bidelman

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,如果同时指定了 leftright,则 left 胜出。同样,如果同时使用 topbottom,系统会优先使用 top

当前支持 Chrome 23.0.1247.0 及更高版本(现行 Canary 版)和 WebKit 每夜版。