滚动条呈现在绝对定位元素上方,用于元素下方的水平滚动容器

Scrollbar renders above absolute positioned element for horizontally scrolling container beneath element

我正在开发一个 React 应用程序,该应用程序在同一页面上包含一个水平滚动视图和一个弹出窗口。我在 Chrome 中测试时注意到一个错误,其中水平滚动视图的滚动条呈现在我放置的弹出窗口的顶部,尽管弹出窗口具有绝对位置。我已将问题缩小为一个简化的示例。这是 Chrome 上的问题的屏幕截图:

我试过以下方法:

这是我整理的一个简化的 HTML 示例,用于演示该问题。

<html>
<head>
    <style type="text/css">
        body {
            overflow: hidden;
            position: relative;
        }

        .container {
            width: 1000px;
            height: 50px;
            overflow: scroll;
            white-space: nowrap;
        }

        .popover {
            width: 200px;
            height: 200px;
            top: 0;
            left: 100px;
            background-color: teal;
            position: absolute;
        }
    </style>
</head>
<body>
<div class="container">
    Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.
</div>
<div class="popover">
    Hi!
</div>

</body>
</html>

我也把这个放到了 JSFiddle.

我希望滚动条呈现在弹出框后面。相反,它呈现在弹出窗口的顶部。

我应该注意到预期的行为发生在 Firefox 上。 Chrome 和 Safari 都出现了这个问题。 (我在 Mac。)

有谁知道如何在 Chrome 和 Safari 上让滚动条呈现在弹出窗口后面?我更喜欢 CSS 解决方案,但由于原始问题出现在较大的 React 应用程序中,我也可以使用一些 JavaScript 来解决问题。

不确定这是否适用于您的大型应用程序,但我相信将弹出窗口位置设置为相对位置,并移动您的 HTML 以便弹出窗口呈现在容器下方应该可以解决问题。我在 Mac 上的 Chrome 中使用了它,效果很好。

<html>
    <head>
        <style type="text/css">
            body {
                overflow: hidden;
                position: relative;
            }

            .container {
                width: 1000px;
                height: 50px;
                overflow: scroll;
                white-space: nowrap;
            }

            .popover {
                width: 200px;
                height: 200px;
                top: 0;
                left: 100px;
                background-color: teal;
                position: relative;
            }
        </style>
    </head>
<body>
    <div class="popover">
        Hi!
    </div>
        <div class="container">
        Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.
    </div>
</body>
</html>

我无法在 macOS Firefox 上重现该错误,但绝对可以在 macOS Chrome 和 Safari 上重现它——这似乎是一个 webkit/blink 渲染问题。您可以使用的一个技巧是强制在元素上进行 GPU 合成:这可以简单地通过使用 transform: translate3d(0,0,0); 来完成。请参阅下面的概念验证示例:

body {
  overflow: hidden;
  position: relative;
}

.container {
  background: yellow;
  width: 1000px;
  height: 50px;
  overflow: scroll;
  white-space: nowrap;
}

.popover {
  width: 200px;
  height: 200px;
  top: 0;
  left: 100px;
  background-color: teal;
  position: absolute;
  transform: translate3d(0,0,0);
}
<div class="container">
  Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor
  in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.
</div>
<div class="popover">
  Hi!
</div>