关于CSS:为什么“溢出:隐藏”会阻止“位置:粘性”起作用?

Why does `overflow:hidden` prevent `position:sticky` from working?

在以下代码段中,在容器内放置了一个粘性div。 它一直粘贴在滚动面板的顶部,同时始终保持在其容器内。 这与iOS上UITableView标头的行为相同,在标头下一个标头位于顶部之前,标头一直可见。

在第二个片段中,除了容器具有overflow:hidden CSS规则之外,其他所有内容都相同。 这似乎阻止position:sticky行为正常工作。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
.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;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
      Hi, I am a sticky inside the container which contains the first paragraph.
   
    <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>

    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><center>[wp_ad_camp_2]</center></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>


 
   
      Hi, I am another sticky in the container which contains the first paragraph, but my container has overflow:hidden.
   
    <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>

    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>

(摘录自@Daniel的代码段)

为什么position:sticky在带有overflow:hidden的容器中不起作用?


overflow: hidden不会阻止position: sticky工作。但是,如果您在粘滞元素的任何祖先上将overflow设置为hidden,则此祖先元素将成为您的粘滞元素的滚动容器。如果将祖先上的overflow值从hidden切换到scroll并滚动此祖先(而不是窗口),则可以看到粘性仍在起作用。

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

Any non-default value (not visible) for overflow, overflow-x, or
overflow-y on any of the predecessor elements anchors the sticky to
the overflow context of that predecessor. Simply speaking, scrolling
the predecessor will cause the sticky to stick, scrolling the window
will not. This is expected with overflow: auto and overflow: scroll,
but often causes problems and confusion with overflow: hidden.

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

The box's position depends on its containing block (established as for
position:static) as well as its scrolling container, defined by the
nearest ancestor in the same document with a computed value for
'overflow-x' or 'overflow-y' other than 'visible', or the viewport if
no such ancestor exists.

或CSS定位版式模块第3级
W3C工作草案:

A stickily positioned box is positioned similarly to a relatively
positioned box, but the offset is computed with reference to the
nearest ancestor with a scrolling box, or the viewport if no ancestor
has a scrolling box.


我不确定这在所有情况下都行得通,但是我已经遇到了这个问题,并且可以通过使用剪切路径替换overflow: hidden;来解决此问题。

1
2
3
4
5
6
7
.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!) */
}

至于必须添加绝对位置,则将overflow:hidden元素包装在另一个位置:相对元素中,然后添加上,下,左和右:0;应该填充它的父容器。


2020解决方案:

我只是遇到了同样的问题,幸运的是overflow-x: hidden可以用类似的属性替换。

就我而言,我想防止在移动视口上水平滚动。因为我主要使用CSS网格,所以我使用SASS / SCSS来解决它:

1
2
3
4
5
6
@include media('<tablet') { // When tablet viewport or smaller
    main {
        display: grid;
        grid-template-columns: 1fr;
        justify-items: center;
...

这样可以防止

标记内的任何元素溢出。

顺便说一句,要支持CSS网格跨浏览器,您只需使用自动前缀即可。


根据Mozilla(在此链接)

Sticky是实验性的API,不应在生产代码中使用。

因此,对我而言,仅这就是它无法正常工作的原因。 Edge和IE 11都不支持它,所以对我来说,用javascript做类似的事情将是前进的方向,那里有很多应该帮助的地方。

一个例子就是这里

希望这可以帮助。