为什么`overflow:hidden`阻止`position:sticky`工作?

che*_*ica 38 css css-position

在下面的代码段中,div容器内部有一个粘性位置.它始终保持在容器内部,并粘在滚动面板的顶部.这与UITableViewiOS上的标题的行为相同,其中标题保持可见,直到下一个标题位于顶部.

在第二个片段中,除了容器具有overflow:hiddenCSS规则之外,一切都是相同的.这似乎可以防止position:sticky行为正常工作.

.parent {
  position: relative;
  background: #ccc;
  width: 500px;
  height: 150px;
  overflow: auto;
  margin-bottom: 20px;
}

.hidden-overflow {
  overflow: hidden;
}

.sticky {
  position: sticky;
  background: #333;
  text-align: center;
  color: #fff;
  top: 10px;
}
Run Code Online (Sandbox Code Playgroud)
<div class="parent">
  <div>
    <div class="sticky">
      Hi, I am a sticky inside the container which contains the first paragraph.
    </div>
    <p>
      Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus volutpat sed metus et porttitor. Integer bibendum lacus eget massa ultricies fermentum. Donec cursus magna eu congue posuere. Sed eget ligula quam. Sed laoreet enim sapien, eget volutpat nisl pellentesque vel. Nulla id dolor sed dolor sodales tristique. Curabitur feugiat massa sed massa bibendum semper et ac orci. In imperdiet nibh quis iaculis viverra. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Quisque vestibulum, nunc non volutpat tristique, nisl nisi volutpat nibh, quis pulvinar purus ex nec justo. Sed a cursus turpis. Quisque nulla odio, lacinia quis vestibulum sit amet, elementum laoreet nisi. Etiam aliquet ligula sagittis,
    consectetur ipsum sit amet, sodales augue.
    </p>
  </div>
  <p>
    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus volutpat sed metus et porttitor. Integer bibendum lacus eget massa ultricies fermentum. Donec cursus magna eu congue posuere. Sed eget ligula quam. Sed laoreet enim sapien, eget volutpat
    nisl pellentesque vel. Nulla id dolor sed dolor sodales tristique. Curabitur feugiat massa sed massa bibendum semper et ac orci. In imperdiet nibh quis iaculis viverra. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos
    himenaeos. Quisque vestibulum, nunc non volutpat tristique, nisl nisi volutpat nibh, quis pulvinar purus ex nec justo. Sed a cursus turpis. Quisque nulla odio, lacinia quis vestibulum sit amet, elementum laoreet nisi. Etiam aliquet ligula sagittis,
    consectetur ipsum sit amet, sodales augue.
  </p>
  <p>
    Integer congue augue a quam tincidunt, vitae dictum sem iaculis. Proin feugiat nibh vitae leo facilisis, eget laoreet augue dictum. Nunc facilisis tempor feugiat. Aenean eget interdum diam. Maecenas non risus iaculis, scelerisque ipsum eu, facilisis urna.
    Integer velit justo, vestibulum vel vulputate vel, bibendum eu lorem. Phasellus viverra nisl a mi pretium eleifend.
  </p>
</div>
<div class="parent">
  <div class="hidden-overflow">
    <div class="sticky">
      Hi, I am another sticky in the container which contains the first paragraph, but my container has overflow:hidden.
    </div>
    <p>
      Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus volutpat sed metus et porttitor. Integer bibendum lacus eget massa ultricies fermentum. Donec cursus magna eu congue posuere. Sed eget ligula quam. Sed laoreet enim sapien, eget volutpat nisl pellentesque vel. Nulla id dolor sed dolor sodales tristique. Curabitur feugiat massa sed massa bibendum semper et ac orci. In imperdiet nibh quis iaculis viverra. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Quisque vestibulum, nunc non volutpat tristique, nisl nisi volutpat nibh, quis pulvinar purus ex nec justo. Sed a cursus turpis. Quisque nulla odio, lacinia quis vestibulum sit amet, elementum laoreet nisi. Etiam aliquet ligula sagittis,
    consectetur ipsum sit amet, sodales augue.
    </p>
  </div>
  <p>
    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus volutpat sed metus et porttitor. Integer bibendum lacus eget massa ultricies fermentum. Donec cursus magna eu congue posuere. Sed eget ligula quam. Sed laoreet enim sapien, eget volutpat
    nisl pellentesque vel. Nulla id dolor sed dolor sodales tristique. Curabitur feugiat massa sed massa bibendum semper et ac orci. In imperdiet nibh quis iaculis viverra. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos
    himenaeos. Quisque vestibulum, nunc non volutpat tristique, nisl nisi volutpat nibh, quis pulvinar purus ex nec justo. Sed a cursus turpis. Quisque nulla odio, lacinia quis vestibulum sit amet, elementum laoreet nisi. Etiam aliquet ligula sagittis,
    consectetur ipsum sit amet, sodales augue.
  </p>
  <p>
    Integer congue augue a quam tincidunt, vitae dictum sem iaculis. Proin feugiat nibh vitae leo facilisis, eget laoreet augue dictum. Nunc facilisis tempor feugiat. Aenean eget interdum diam. Maecenas non risus iaculis, scelerisque ipsum eu, facilisis urna.
    Integer velit justo, vestibulum vel vulputate vel, bibendum eu lorem. Phasellus viverra nisl a mi pretium eleifend.
  </p>
</div>
Run Code Online (Sandbox Code Playgroud)

(片段改编自丹尼尔@的位置)

为什么不在position:sticky容器中工作overflow:hidden

sea*_*pip 90

自从这个问题最初发布以来已经有几年了,现在有另一种方法来隐藏溢出的内容:

contain: paint;
Run Code Online (Sandbox Code Playgroud)

https://developer.mozilla.org/en-US/docs/Web/CSS/contain

  • 仅使用“contain:paint”来剪切溢出内容是一个非常糟糕的主意,因为它还有其他副作用。而是使用“overflow:clip” (5认同)
  • 这是可行的,但它会弄乱其中任何项目的固定位置。https://developer.mozilla.org/en-US/docs/Web/CSS/Containing_block#identifying_the_having_block (4认同)
  • @ydaniv 嘿,我刚刚听了你的建议,并使用了“overflow:clip”,效果很好!您是否愿意解释一下“overflow:clip”与“overflow:hidden”有何不同,以及为什么它比“contain:paint”更好? (2认同)

cha*_*enu 44

overflow: hidden并没有阻止position: sticky工作.但是如果设置overflowhidden粘性元素的任何祖先,则此祖先元素将是粘性元素的滚动容器.如果您overflow将祖先的值从中切换hiddenscroll并滚动此祖先(而不是窗口),那么您可以看到粘性仍然有效.

另请参见https://github.com/wilddeer/stickyfill#pro-tips:

任何前驱元素上的overflow,overflow-x或overflow-y的任何非默认值(不可见)都将sticky粘贴到该前任的溢出上下文中.简单来说,滚动前一个将导致粘贴,滚动窗口不会.这是溢出的预期:自动和溢出:滚动,但经常导致问题和溢出混淆:隐藏.

或者http://www.coreyford.name/files/position-sticky-presentation/:

框的位置取决于其包含块(建立为position:static)以及其滚动容器,由同一文档中最近的祖先定义,其中'overflow-x'或'overflow-y'的计算值除外'visible',或视口,如果不存在这样的祖先.

CSS定位布局模块3级W3C工作草案:

粘性定位的盒子与相对定位的盒子类似地定位,但是偏移是参考具有滚动框的最近祖先计算的,或者如果没有祖先具有滚动框则计算视口.

  • 我应该指出,带有祖先 `overflow` 从 `hidden` 到 `scroll` 的 `sticky` 仅在设置了祖先容器的高度时才有效,在这种情况下,您将能够滚动容器而不是窗口。 (3认同)
  • 好的。使用“overflow-x:hidden;”时是否可以防止这种情况? (3认同)

she*_*ock 27

我遇到了这个问题并找到了替代解决方案,使用而overflow: clip不是overflow: hidden. 据我所知,它们的工作方式几乎相同,只是粘性元素的锚点在使用时不受影响clip。唯一的问题是,截至 2022 年 11 月,overflow: clip浏览器支持有限(~80%): https: //caniuse.com/mdn-css_properties_overflow_clip


mar*_*ite 10

我不确定这在所有情况下都有效,但我遇到了这个问题,并且能够通过替换overflow: hidden;clip-paths来解决这个问题。

.parent {
    /*overflow: hidden; removed */
    position: absolute; /*this is required for clip-paths to work*/
    -webkit-clip-path: inset(0); /* safari*/
    clip-path: inset(0);
    clip: rect(0px, auto, auto, 0px); /* IE11/Edge (not that IE11 supports sticky anyway!) */
}
Run Code Online (Sandbox Code Playgroud)

至于必须添加绝对位置,将溢出:隐藏元素包装在另一个位置:相对元素,然后添加顶部,底部,左侧和右侧:0;应该让它填满它的父容器。

  • https://caniuse.com/#search=clip-path 如果有人想知道浏览器与这种聪明方法的兼容性。 (2认同)