神奇的position:sticky

本文介绍了使用 CSS 的 position:sticky 属性实现导航栏随滚动定位顶部的效果,并对比了传统 JavaScript 监听滚动事件的方法。sticky 属性允许元素在滚动到特定位置时保持固定,而不会脱离文档流。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

神奇的position:sticky

sticky定义

position:sticky定义,
eg:CSS中position属性介绍(新增sticky)

设置了sticky的元素,在屏幕范围(viewport)时该元素的位置并不受到定位影响(设置是top、left等属性无效),当该元素的位置将要移出偏移范围时,定位又会变成fixed,根据设置的left、top等属性成固定位置的效果。

sticky特点

sticky属性有以下几个特点:

  1. 该元素并不脱离文档流,仍然保留元素原本在文档流中的位置。
  2. 当元素在容器中被滚动超过指定的偏移值时,元素在容器内固定在指定位置。亦即如果你设置了top: 50px,那么在sticky元素到达距离相对定位的元素顶部50px的位置时固定,不再向上移动。
  3. 元素固定的相对偏移是相对于离它最近的具有滚动框的祖先元素,如果祖先元素都不可以滚动,那么是相对于viewport来计算元素的偏移量。

sticky的demo

sticky展现效果

看了效果我就会很清楚的知道他的作用,在实际应用中,eg:导航栏随屏幕滚动定位顶部,侧边栏广告随滚动定位顶部等。

以导航栏随屏幕滚动定位顶部为实例:

方案一:双导航实现原理

  1. 一个导航(1)在商品的上方(初始化导航一显示),一个导航(2)定位在窗口的顶部(初始化导航二隐藏);
  2. 然后实现滚动监听事件:

    1. 当滚动到大于等于导航(1)的位置时,导航(2)显示(导航一此时依然显示,只是我们用导航二层级将导航一遮挡)————-此时我们看到窗口顶部的导航是:导航(2)
    2. 当滚动到小于导航(1)的位置时,导航(2)隐藏(导航一显示)————–此时我们看到商品顶部的导航是:导航(1)

    优点:

    1. 兼容性比较好;
    2. 不会出现抖动的效果;
    3. 不会导致回流。

    缺点:

    1. 代码量较多;
    2. 浏览器计算消耗大;
    3. 在切换的时候会出现闪动的效果。
CSS代码
.module-nav{
    color: #ffea00;
    width: 7rem;
    font-size: 0.28rem;
    height: 0.65rem;
    line-height: 0.6rem;
    display: table;
    table-layout: fixed;
    padding: 0 0.25rem;
    text-align: center;
    background: #fbbd09;
}
.module-nav.nav1{
    position: fixed;
    top: 0;
    left: 0;
    z-index: 10000;
    display:none;
}
.module-nav span{
    display: table-cell;
    background: url(./images/nav-bg.jpg) no-repeat right center/1.7rem 0.65rem;
}
.module-nav span.active{color: #fff;}
HTML代码
<nav class="module-nav">
    <span class="active">生态餐桌</span>
    <span>茗茶名酒</span>
    <span>美食物语</span>
    <span>居家生活</span>
</nav>
<nav class="module-nav nav1">
    <span class="active">生态餐桌</span>
    <span>茗茶名酒</span>
    <span>美食物语</span>
    <span>居家生活</span>
</nav>
JS代码
$(window).scroll(function(){
    var bodyTop = $('html,body').scrollTop();
    var goodTop = $('.goods').offset().top;
    bodyTop >= goodTop ? $('.nav1').show() : $('.nav1').hide();
});

注意:在移动端如果导航要居中显示,要对nav1的left进行计算赋值。

方案二:单导航

通过对导航的position的值在fixed和relative切换,来实现

优点:

  1. 比第一种方案少了一个导航,直接在一个导航操作

缺点:

  1. 依然需要JS来监听,进行position的值切换
  2. 切换时会导致回流
  3. 切换回导致每个楼层的offset().top值的改变,所以每次都需要重新获取
CSS代码
.module-nav{
    position: relative;
    top: 0;
    left: 0;
    z-index: 10000;
    color: #ffea00;
    width: 7rem;
    font-size: 0.28rem;
    height: 0.65rem;
    line-height: 0.6rem;
    display: table;
    table-layout: fixed;
    padding: 0 0.25rem;
    text-align: center;
    background: #fbbd09;
}
.module-nav span{
    display: table-cell;
    background: url(./images/nav-bg.jpg) no-repeat right center/1.7rem 0.65rem;
}
.module-nav span.active{color: #fff;}
HTML代码
<nav class="module-nav">
    <span class="active">生态餐桌</span>
    <span>茗茶名酒</span>
    <span>美食物语</span>
    <span>居家生活</span>
</nav>
JS代码
$(window).scroll(function(){
    var bodyTop = $('html,body').scrollTop();
    var goodTop = $('.goods').offset().top;
    bodyTop >= goodTop ? $('.module-nav').css('position','fixed') : $('.module-nav').css('position','');
});

注意:在fixed定位的时候需要进行left的计算,否则会导致导航的不居中。

方案三:sticky实现原理

直接对导航使用position:sticky,就能实现上边看着复杂的效果。

优点:

  1. 代码量少;
  2. 不用JS监听滚动事件,减少了浏览器计算的消耗;
  3. 不会触发 BFC。BFC详解

缺点:

  1. 兼容性不是很好;
  2. sticky 是容器相关的,也就说 sticky 的特性只会在他所处的容器里生效。看看这个demo你就明白了
CSS代码
.module-nav{
    position: sticky;
    top: 0;
    left: 0;
    z-index: 10000;
    color: #ffea00;
    width: 7rem;
    font-size: 0.28rem;
    height: 0.65rem;
    line-height: 0.6rem;
    display: table;
    table-layout: fixed;
    padding: 0 0.25rem;
    text-align: center;
    background: #fbbd09;
}
.module-nav span{
    display: table-cell;
    background: url(./images/nav-bg.jpg) no-repeat right center/1.7rem 0.65rem;
}
.module-nav span.active{color: #fff;}
HTML代码
<nav class="module-nav">
    <span class="active">生态餐桌</span>
    <span>茗茶名酒</span>
    <span>美食物语</span>
    <span>居家生活</span>
</nav>

注意:由于兼容性问题,所以sticky可以在移动端使用,代码简单,容易理解。但是要注意所选择的容器!

其他

我的博客,欢迎交流!

我的优快云博客,欢迎交流!

微信小程序专栏

前端笔记专栏

微信小程序实现部分高德地图功能的DEMO下载

微信小程序实现MUI的部分效果的DEMO下载

微信小程序实现MUI的GIT项目地址

微信小程序实例列表

前端笔记列表

游戏列表

posted @ 2017-11-21 13:54 Newman·Li 阅读( ...) 评论( ...) 编辑 收藏
<think>我们正在讨论position:sticky的使用方法。根据引用内容,position:sticky是一种粘性定位,它可以让元素在滚动到特定位置时固定在屏幕上(如顶部),直到其滚动容器离开视口。关键点(来自引用[1]和[3]):1.设置:需要同时指定位置(如top,bottom,left,right)之一,例如`top:0`。2.父容器:sticky元素相对于最近的滚动祖先容器定位。如果父容器没有设置高度或没有产生滚动,则可能无效。3.注意事项:-父元素的高度必须大于sticky元素的高度。-如果父元素没有设置高度,那么父元素不能设置overflow为visible以外的值(如auto、scroll),否则可能会影响sticky效果。-如果父元素设置了高度,并且子元素高度超过了父元素高度(出现滚动条),那么sticky在滚动时会生效。-如果父元素设置了高度,但子元素高度没有超过父元素高度(没有滚动),则sticky仅在父元素高度范围内有效。另外,引用[2]给出了一个吸顶效果的例子,其中h2元素在滚动到容器顶部时固定。使用步骤:1.为需要实现粘性定位的元素设置`position:sticky`(注意浏览器前缀,如-webkit-sticky)。2.指定定位值,例如`top:0`(表示当元素滚动到距离视口顶部0px时固定)。3.确保父容器是滚动容器(即设置了overflow:auto或scroll等,并且内容超出容器高度产生滚动条)。示例代码(基于引用[2]简化):```html<style>.container{height:200px;/*设置高度,产生滚动*/overflow:auto;}.sticky-header{position:sticky;top:0;/*当元素到达容器顶部时固定*/background:orangered;color:white;}</style><divclass="container"><divclass="content"><divclass="sticky-header">标题</div><p>内容1</p><p>内容2</p><!--更多内容使容器出现滚动--></div></div>```注意:如果sticky元素没有生效,检查以下几点:-是否指定了top等定位属性?-父容器是否产生了滚动(即内容高度大于容器高度)?-父容器的overflow属性是否允许滚动(非visible)?-父容器的高度是否大于sticky元素的高度?兼容性:IE/Edge15及更早版本不支持,其他现代浏览器支持良好。相关问题:1.position:stickyposition:fixed有什么区别?2.如何让position:sticky在横向滚动时也生效?3.多个sticky元素嵌套时如何控制它们的固定行为?</think>### 如何使用 CSS 中的 `position: sticky` 属性 `position: sticky` 是一种混合定位模式,元素在滚动到阈值位置前保持相对定位,到达阈值后变为固定定位。以下是详细使用指南: #### 核心语法 ```css .element { position: -webkit-sticky; /* Safari 兼容 */ position: sticky; top: 0; /* 触发阈值(必需) */ } ``` #### 使用步骤 1. **基础设置**: ```css .sticky-element { position: sticky; top: 20px; /* 距离视口顶部 20px 时触发 */ } ``` 2. **父容器要求**: - 父元素高度必须大于 sticky 元素高度[^1] - 父容器需设置 `overflow` 属性(非 `visible`): ```css .parent { height: 500px; /* 明确高度 */ overflow: auto; /* 或 scroll */ } ``` 3. **阈值方向**: ```css /* 顶部固定 */ .sticky-top { top: 0; } /* 底部固定 */ .sticky-bottom { bottom: 0; } /* 左侧固定 */ .sticky-left { left: 0; } /* 右侧固定 */ .sticky-right { right: 0; } ``` #### 实际案例 实现文章标题滚动吸顶效果: ```html <style> .container { height: 300px; overflow: auto; /* 必需 */ border: 1px solid #ccc; } .article h2 { position: sticky; top: 0; /* 滚动到顶部时固定 */ background: #4CAF50; color: white; padding: 10px; } </style> <div class="container"> <div class="article"> <h2>第一章标题</h2> <p>内容...</p> </div> <div class="article"> <h2>第二章标题</h2> <!-- 滚动到此标题时固定 --> <p>内容...</p> </div> </div> ``` [在线演示参考](https://codepen.io/anon/pen/ExrLqVK) #### 注意事项 1. **必须指定阈值**:`top/bottom/left/right` 至少设置一个[^1] 2. **滚动容器限制**:只对最近的滚动祖先生效[^3] 3. **父容器高度**: - 内容高度 > 容器高度 → 滚动生效 - 内容高度 < 容器高度 → 仅在容器内有效[^1] 4. **层级控制**:通过 `z-index` 解决元素覆盖问题 5. **兼容性处理**: ```css .sticky { position: -webkit-sticky; /* Safari */ position: sticky; } ``` #### 与 fixed 定位的区别 | 特性 | `sticky` | `fixed` | |---------------------|-----------------------------------|---------------------------| | 定位基准 | 最近的滚动容器 | 浏览器视口 | | 是否脱离文档流 | 否 | 是 | | 滚动行为 | 在容器内固定 | 全局固定 | | 典型应用 | 表格标题、分段导航 | 全局导航栏、悬浮按钮 | | 性能影响 | 较小 | 可能引发重绘 | > ⚠️ **常见问题**:如果 sticky 无效,检查:① 是否设置阈值 ② 父容器是否有滚动条 ③ 父容器高度是否足够[^1][^3] ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值