遇到一个问题,两个页面一个sticky生效,一个不生效,查看了好久,根据文档说父元素不能使用 overflow: hidden 属性,否则sticky无效

1 问题处理

我看了看我的代码,父元素并没有这个属性啊,但是依旧无效,很好奇,后来我发现给他同级元素下面一个子元素加个属性居然可以解决

如图所示,我给A元素设了一个sticky的属性,结果发现并不会磁铁固定住,但是后来我给B下面的b来了一个overflow:hidden 的属性,A立刻磁贴住了

我感觉应该是这不是根本原因,但是也找不到更好的处理办法,这个属性对b没有影响,正好可以用上,也不算逾越

我是百思不得其解,暂时先记录一下这个问题,然后在查阅资料的时候发现一篇文章,感觉总结的不错,就转载过来了。。


转载自:https://www.jianshu.com/p/b72f504121f5

2 基本用法

  nav{
    position:sticky;
    top:10px; /* 阈值 */
    }

2.1 top/bottom属性

top,bottom的距离阈值取决于最近一个overflow是hidden scroll auto或 overlay 的祖先元素(并不是相对于viewport 视口)。

例如我们设置top:100px时,在元素滚动到距离祖先元素顶部小于设置的top:100px之前,元素为相对定位。当滚动到超过或等于top:100px时,元素将固定在与祖先元素顶部距离 top:100px 的相对位置,直到距离回滚到阈值以下。

根据下面的例子,我们可以看到position:sticky元素设置的top值是最近一个设置了overflow的祖先元素的距离,当它滚到距离低于其值时将固定在视口当中,此时该元素的效果就为固定定位。

下面例子的结构:

<div class="container">
  <div class="left">右边距离顶部有margin-top: 100px</div>
  <div class="right">
    <h1 style="height:200px;">顶部高200px 红线为中线</h1>
    <nav>这是导航 top:100px</nav>
    <p>滚一个</p>
    <p>滚一个</p>
    <p>滚一个</p>
    <p>滚一个</p>
    <p>到底啦!</p>
  </div>
</div>
<style>
    /*  精简的部分  */
    .container {
        display: flex;
    }
    .left {
        width: 30%;
        border: 1px solid;
    }
    .right {
        border: 1px solid red;
        width: 100%;
        margin-top: 40px;
        /*  祖先元素为 auto scroll hidden  */
        overflow: scroll; 
        height: 400px;
    }
    nav {
        position: sticky;
        top: 100px;
    }
</style>

3 总结

  1. top、bottom 的生效距离由最近一个overflow属性是hidden scroll auto或 overlay 的祖先元素决定。
  2. 父元素为overflow:hidden时,由于容器内无法滚动,所以实际上也无法生效。
  3. 必须指定top、bottom、left、right4个值之一,否则只会处于相对定位。
  4. 父元素的高度不能低于sticky元素的高度。

4 兼容

  position: -webkit-sticky;
  position: sticky;