【问题标题】:Flexbox/position scrolling discrepancy between Chrome and FirefoxChrome 和 Firefox 之间的 Flexbox/位置滚动差异
【发布时间】:2018-07-02 23:34:52
【问题描述】:

我有一个 position:fixed 叠加层,我正在填充导航和内容,如下图所示:https://jsfiddle.net/9871Lz1u/1/

我在固定位置的 div 中使用 flexbox,来控制导航按钮的位置,并使用相对定位的 div 来容纳内容。使用 Chrome,这完全符合预期。但是,使用 Firefox/Safari(最新版本)时,我发现将光标悬停在 flexbox(红色和蓝色)区域上时,滚动被锁定。我必须将光标悬停在白色内容框上才能“启用”滚动。

我希望 Chrome 行为,无论光标在哪里都允许滚动,成为最终的一致行为。此外,如果可能的话,我希望解决方案是纯 HTML/CSS。

我的系统:macOS 版本 10.13.2、Chrome 版本 63.0.3239.132、Firefox 版本 58.0

.container {
  background: black;
  display: block;
  position: fixed;
  top: 0px;
  left: 0px;
  right: 0px;
  bottom: 0px;
  overflow: auto;
}

.content {
  background: white;
  margin: auto;
  max-width: 400px;
  padding: 15px;
  z-index: 2;
  position: relative;
	overflow: auto;
}

.nav-outer {
  position:fixed;
	top: 0px;
	bottom: 0px;
	left: 0px;
	right: 0px;
  z-index: 1;
}

.nav-inner {
  display: flex;
	width: 100%;
	height: 100%;
	flex-direction: row;
	flex-wrap: nowrap;
}

.nav-center {
  flex: 1 100%;
	order: 2;
	max-width: 400px;
}

.nav-container {
  flex: 1 auto;
	display: -ms-flexbox;
	display: -webkit-flex;
	display: flex;
	/* -ms-flex-align: center;
	-webkit-align-items: center;
	-webkit-box-align: center; */
	align-items: center;
	overflow: hidden;
}

.nav-left {
  order: 1;
  background: red;
}

.nav-right {
  order: 3;
  background: blue;
}

.nav-button {
  width: 70px;
	height: 70px;
	border-radius: 50%;
	background-color: black;
	display: block;
	z-index: 10;
	margin: auto;
	background-repeat: no-repeat;
	background-size: 40px 40px;
	border: 1px solid white;
}
<div class="container">
  <div class="content">
    Some overflowable content<br/>
    Some overflowable content<br/>
    Some overflowable content<br/>
    Some overflowable content<br/>
    Some overflowable content<br/>
    Some overflowable content<br/>
    Some overflowable content<br/>
    Some overflowable content<br/>
    Some overflowable content<br/>
    Some overflowable content<br/>
    Some overflowable content<br/>
    Some overflowable content<br/>
    Some overflowable content<br/>
    Some overflowable content<br/>
    Some overflowable content<br/>
    Some overflowable content<br/>
    Some overflowable content<br/>
    Some overflowable content<br/>
    Some overflowable content<br/>
    Some overflowable content<br/>
    Some overflowable content<br/>
    Some overflowable content<br/>
    Some overflowable content<br/>
    Some overflowable content<br/>
    Some overflowable content<br/>
    Some overflowable content<br/>
    Some overflowable content<br/>
  </div>
  <div class="nav-outer">
    <div class="nav-inner">
      <div class="nav-container nav-left">
        <div class="nav-button"></div>
      </div>
      <div class="nav-center"></div>
      <div class="nav-container nav-right">
        <div class="nav-button"></div>
      </div>
    </div>
  </div>
</div>

【问题讨论】:

  • 确保小提琴中的输出窗口足够短以至于有溢出,并且足够宽以至于你可以看到红色/蓝色条带。在滚动滚轮时将光标悬停在彩色条上应该会在 Chrome 中滚动内容 div,但在 FF 中则不会。

标签: javascript html css flexbox


【解决方案1】:

浏览器处理这个问题的一般方式是滚动有光标的元素。

即使是 Chrome 也可以,您可以在 stack sn-p 中看到(当不在“扩展模式”时),如果光标没有结束,它将滚动整个 stackoverflow 页面可滚动文本,以及在 fiddle 中,如果您从红色或蓝色元素开始滚动。

但是,如果您第一次滚动文本,Chrome 会继续滚动它,即使在光标移动到红色或蓝色元素之后,我的猜测是它会记住最后一次滚动,保持它具有 滚动焦点,直到另一个元素获得焦点。

因此,使用现有标记,您将需要一个脚本来完成此操作,这里有一个示例,使用 jQuery:


通过更改标记,您无需脚本即可摆脱困境,只需删除 container

这对布局没有影响,因为body 或多或少与固定的container 具有完全相同的行为,因此滚动的将是body,并且可以跨浏览器工作.

Updated fiddle

堆栈sn-p

body {
  background: black;
  margin: 0;
}

.content {
  background: white;
  margin: auto;
  max-width: 400px;
  padding: 15px;
  z-index: 2;
  position: relative;
  overflow: auto;
}

.nav-outer {
  position: fixed;
  top: 0px;
  bottom: 0px;
  left: 0px;
  right: 0px;
  z-index: 1;
}

.nav-inner {
  display: flex;
  width: 100%;
  height: 100%;
  flex-direction: row;
  flex-wrap: nowrap;
}

.nav-center {
  flex: 1 100%;
  order: 2;
  max-width: 400px;
}

.nav-container {
  flex: 1 auto;
  display: -ms-flexbox;
  display: -webkit-flex;
  display: flex;
  /* -ms-flex-align: center;
	-webkit-align-items: center;
	-webkit-box-align: center; */
  align-items: center;
  overflow: hidden;
}

.nav-left {
  order: 1;
  background: red;
}

.nav-right {
  order: 3;
  background: blue;
}

.nav-button {
  width: 70px;
  height: 70px;
  border-radius: 50%;
  background-color: black;
  display: block;
  z-index: 10;
  margin: auto;
  background-repeat: no-repeat;
  background-size: 40px 40px;
  border: 1px solid white;
}
<div class="content">
  Some overflowable content
  <br/> Some overflowable content
  <br/> Some overflowable content
  <br/> Some overflowable content
  <br/> Some overflowable content
  <br/> Some overflowable content
  <br/> Some overflowable content
  <br/> Some overflowable content
  <br/> Some overflowable content
  <br/> Some overflowable content
  <br/> Some overflowable content
  <br/> Some overflowable content
  <br/> Some overflowable content
  <br/> Some overflowable content
  <br/> Some overflowable content
  <br/> Some overflowable content
  <br/> Some overflowable content
  <br/> Some overflowable content
  <br/> Some overflowable content
  <br/> Some overflowable content
  <br/> Some overflowable content
  <br/> Some overflowable content
  <br/> Some overflowable content
  <br/> Some overflowable content
  <br/> Some overflowable content
  <br/> Some overflowable content
  <br/> Some overflowable content
  <br/>
</div>
<div class="nav-outer">
  <div class="nav-inner">
    <div class="nav-container nav-left">
      <div class="nav-button"></div>
    </div>
    <div class="nav-center"></div>
    <div class="nav-container nav-right">
      <div class="nav-button"></div>
    </div>
  </div>
</div>

【讨论】:

  • 你的第一个推荐成功了。我希望我可以摆脱绑定任何滚轮事件,但没有这样的运气。 (正如我在问题中提到的,这一切都发生在模态覆盖中,因此固定容器是必要的)。此外,如果有人像我一样使用 React,我最终会在 nav-outer 元素上执行 onWheel = {this.onWheel.bind(this)},然后使用 e.deltaY 手动调整 content 元素的滚动位置。