Safari position:sticky 在 overflow:auto 元素中不工作
Safari position:sticky not working in an overflow:auto element
根据 CanIUse,Safari 和 position:sticky
在 overflow: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;
根据 CanIUse,Safari 和 position:sticky
在 overflow: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;