Safari position:sticky 在 overflow:auto 元素中不工作

Safari position:sticky not working in an overflow:auto element

根据 CanIUse,Safari 和 position:stickyoverflow:auto 元素中存在一个已知问题:

A parent with overflow set to auto will prevent position: sticky from working in Safari

但是,这正是我需要的用例。我有一个可滚动的 div,它被子 div 分为两列。右栏应该是粘性的并且永远不会移动,即使整个 div 被滚动也是如此。我在右栏上使用 position:sticky 的原因是我希望用户仍然能够在光标位于右栏的情况下滚动左栏。这是我发现唯一有效的解决方案。

Firefox 的工作示例/Chrome 在这里: http://cssdeck.com/labs/zfiuz4pc 滚动时橙色区域保持固定,但在 Safari 中则不然。

上面的例子对我的问题有一些不必要的包装,但我想尽可能地复制我想让这段代码工作的环境。它的基本要点是我有这个:

<div class="modal-content">
  <div class="left-content">
  </div>
  <div class="sticky-element">
  </div>
</div>

和 CSS:

.modal-content {
  display: flex;
  overflow: auto;
  flex-flow: row nowrap;
}

.left-content {
  flex: 0 0 300px;
}

.sticky-element {
  position: sticky;
  top: 0;
  right: 0;
  width: 200px;
}

同样,这在 FF/Chrome 中有效,但在 Safari 中无效。是否有解决方法让它在所有浏览器中工作?或者是否有一种不同的方法可以用来保持可滚动性,即使鼠标光标悬停在粘性元素上也是如此?

我现在无法真正针对 safari 进行测试,但是在创建粘性页脚时,这一直是我的替代方案:

<!DOCTYPE html>
<html>
<head>
    <title>sticky side div</title>
    <style type="text/css">
        .maindiv{
            position: relative;
            display: inline-block;
            background-color: forestgreen;
            width: calc(100vw - 150px);
            height: 100%;
            overflow: auto;
        }
        .sidediv{
            position: fixed;
            display: inline-block;
            background-color: lightyellow;
            float: right;
            width: 100px;
            height: 100%;
        }
    </style>
</head>
<body>
    <div class="maindiv">
        Lorem 45    
    </div>
    <div class="sidediv">
        Lorem 30
    </div>
    <div class="maindiv">
        Lorem 100
    </div>
    <div class="maindiv">
        Lorem 900
    </div>
</body>
</html>

一旦您知道正确内容的宽度,请向其添加更多像素,然后使用 css calc function 确保其他 div 不会流动加入其中

Safari 7 中的 vh 和 vw 也有一个已知错误。您可以通过设置高度来修复它:继承父元素具有 vh 高度或 vw 宽度的 #child 元素

但如果您不打算获得跨浏览器支持,我最好的建议是使用 CSS Grids

我从别人那里得到了这个解决方案:

http://cssdeck.com/labs/bu0nx69w

基本上,右面板使用 position:fixed 而不是 position:sticky。关键是你 will-change:transform 在父 div 中(在上面的例子中,在 .modal-content 中)所以 position:fixed 相对于那个父而不是视口变得固定。这是一个巧妙的小技巧

只需添加position: -webkit-sticky;

针对此特定情况的另一种解决方案,只要您不需要模态窗口最右侧的滚动条即可。

由于您的粘性元素与 .modal-content 的高度相同,您可以从 .sticky-element 中完全移除粘性元素。首先,从 .modal-content 中删除 overflow:auto,然后将该样式添加到 .left-content,因为这是您想要滚动的部分。

display: block 添加到 .sticky-element 对我来说很有效,而无需添加 position: -webkit-sticky。在 this Codepen.

找到了这个解决方案

我有一个类似的案例:

<div scroll>
    <div sticky />
    <list />
</div>

只需用 div 包裹滚动内容就可以了:

<div scroll>
    <div>
       <div sticky />
       <list />
    </div>
</div>
如果您的父元素具有 overflow: hidden

position: sticky 将不起作用。使用此 sticky 设置,它会自动将您的元素从 relative to actual fixed 转换为文档的顶部边框。

我必须使用下面的代码才能在 Chrome 和 Safari 中使用:

position: sticky;
position: -webkit-sticky;
display: block;