今天才发现 position 还有一个 sticky 属性。
前端开发中一个常见需求:当页面滚动某处时,让一部分内容固定在某处。以往必须要监听 scroll 事件,然后改变样式。这种方式有几个问题:
- 每滚动一定距离后才会触发 scroll 事件,从滚动到固定过程会出现抖动,不够平滑。
- 监听滚动事件消耗性能。
- 增加代码复杂度。
sticky 定位的 Element 有两种表现,并且要配合 top、right、bottom 和 left 设置偏移值。
- 在偏移值内,行为等同
relative定位,按正常文档流定位。 - 超过偏移值后,类似
fix定位。
以 top: 10px 为例(假设仅页面滚动):
- 在 Element 距离 Viewport(可视范围内)顶部大于
10px时,为相对定位。 - 滚动页面后,Element 移动距离顶部小于
10px时,固定到距离顶部10px位置。
与 fix 定位不同,sticky Element 不一定是相对 Viewport 定位,它的参考对象是祖先 Elemetn 中,最近的**,具有滚动机制**(overflow 等于 hidden, scroll, auto ,)或能滚动的 Element。如果祖先元素都不具有滚动机制,sticky Element 参考对象才是 Viewport。
由于机制特殊,相对 Viewport 定位要注意以下情况:
- 父元素不能
overflow: hidden或者overflow: auto属性。 - 必须指定
top、bottom、left、right4个值之一,否则只会处于相对定位 - 父元素的高度不能低于
sticky元素的高度 sticky元素仅在其父元素内生效
优先级 top 大于 bottom,left 大于 right。
sticky 优点:
- 切换流畅,没有卡顿。
- 性能好。
- 方便在任意滚动元素内实现该机制。
sticky 缺点:
- 机制复杂。
- 对祖先元素有要求。
top、bottom、left、right不能同时指定 Element 两侧偏移。- 兼容性稍差