sticky定义
position:sticky定义,
eg:CSS中position属性介绍(新增sticky)
设置了sticky的元素,在屏幕范围(viewport)时该元素的位置并不受到定位影响(设置是top、left等属性无效),当该元素的位置将要移出偏移范围时,定位又会变成fixed,根据设置的left、top等属性成固定位置的效果。
sticky特点
sticky属性有以下几个特点:
- 该元素并不脱离文档流,仍然保留元素原本在文档流中的位置。
- 当元素在容器中被滚动超过指定的偏移值时,元素在容器内固定在指定位置。亦即如果你设置了top: 50px,那么在sticky元素到达距离相对定位的元素顶部50px的位置时固定,不再向上移动。
- 元素固定的相对偏移是相对于离它最近的具有滚动框的祖先元素,如果祖先元素都不可以滚动,那么是相对于viewport来计算元素的偏移量。
sticky的demo
看了效果我就会很清楚的知道他的作用,在实际应用中,eg:导航栏随屏幕滚动定位顶部,侧边栏广告随滚动定位顶部等。
以导航栏随屏幕滚动定位顶部为实例:
方案一:双导航实现原理
- 一个导航(1)在商品的上方(初始化导航一显示),一个导航(2)定位在窗口的顶部(初始化导航二隐藏);
然后实现滚动监听事件:
- 当滚动到大于等于导航(1)的位置时,导航(2)显示(导航一此时依然显示,只是我们用导航二层级将导航一遮挡)————-此时我们看到窗口顶部的导航是:导航(2)
- 当滚动到小于导航(1)的位置时,导航(2)隐藏(导航一显示)————–此时我们看到商品顶部的导航是:导航(1)
优点:
- 兼容性比较好;
- 不会出现抖动的效果;
- 不会导致回流。
缺点:
- 代码量较多;
- 浏览器计算消耗大;
- 在切换的时候会出现闪动的效果。
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切换,来实现
优点:
- 比第一种方案少了一个导航,直接在一个导航操作
缺点:
- 依然需要JS来监听,进行position的值切换
- 切换时会导致回流
- 切换回导致每个楼层的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,就能实现上边看着复杂的效果。
优点:
- 代码量少;
- 不用JS监听滚动事件,减少了浏览器计算的消耗;
- 不会触发 BFC。BFC详解
缺点:
- 兼容性不是很好;
- 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可以在移动端使用,代码简单,容易理解。但是要注意所选择的容器!