在开发过程时,有没有遇到过这么一种情况 —— 网站滚动到一定高度的时候,让一部分内容作为navbar,也就是置顶显示。我们一般会使用js监听scroll事件来实现,但是新增的css属性position:sticky可以简单实现。
简介
sticky 英文字面意思是粘,粘贴,所以可以把它称之为粘性定位。
position: sticky; 基于用户的滚动位置来定位。
粘性定位的元素是依赖于用户的滚动,在 position:relative 与 position:fixed 定位之间切换。
在目标区域以内,它的行为就像 position:relative; 在滑动过程中,某个元素距离其父元素的距离达到sticky粘性定位的要求时(比如top:100px);position:sticky;这时的效果相当于position:fixed;,它会固定在目标位置。
元素定位表现为在跨越特定阈值前为相对定位,之后为固定定位。可以说是相对定位relative和固定定位fixed的结合。
元素固定的相对偏移是相对于离它最近的具有滚动框的祖先元素,如果祖先元素都不可以滚动,那么是相对于viewport来计算元素的偏移量。
使用条件
1.父级元素不能有任何overflow:visible以外的overflow设置,否则没有粘滞效果
2.必须指定top、bottom、left、right4个值之一,否则只会处于相对定位 。
3.父元素的高度不能低于sticky元素的高度
4、sticky元素仅在其父元素内生效
特性(坑)
1、sticky 不会触发 BFC。
2、样式表 z-index 无效。行内 style 写有效。
写法
div.sticky {
position: -webkit-sticky;
position: sticky;
top: 20px;
}
常见示例:滚动吸顶导航
最典型的用法——页面滚动时,导航条滚到距顶部 20px 处就”粘”在屏幕上:
<div class="nav">我是导航</div>
<div class="content">
<!-- 很长的正文内容 -->
</div>
<style>
.nav {
position: -webkit-sticky;
position: sticky;
top: 20px; /* 距视口顶部 20px 时吸住 */
background: #fff;
z-index: 10;
}
</style>
另一个常用场景是表格首行/首列固定:
thead th {
position: sticky;
top: 0; /* 表头滚到顶部时固定 */
background: #f5f5f5;
}
为什么不生效(排查清单)
按”使用条件”逐条对:
- 没写
top/bottom/left/right→ 它只会是相对定位,不会粘。必须至少指定一个阈值。 - 父元素设了
overflow: hidden / auto / scroll(除visible)→ sticky 失效。这是最常见的坑,检查祖先元素。 - 父元素高度不够 → 父元素滚完之前 sticky 就”没空间”可粘了,表现为正常滚动。确保父容器足够高。
- 生效范围只在父元素内 → 元素滚出父元素后就会跟着父元素一起走,不会一直固定在视口。
一句话:sticky 是”在父元素内部、到达阈值时临时 fixed”,所以父元素的高度和
overflow是它能否生效的关键。