在一个flex子元素上设置overflow-y: auto,且高度为100vh时,Safari无法滚动——只有橡皮筋滚动效果

移动开发 2026-07-09

我有一个三栏的作品集布局。每个列都是一个全高度的flex行的flex子项,应该独立滚动。它在Chrome中运行良好,但在Safari中,列只显示橡皮筋弹跳——没有真正的滚动。

布局(简化):

<div class="container">
  <div class="column">
    <div class="wrapper">
      <!-- lots of content -->
    </div>
  </div>
</div>

.container {
  display: flex;
  height: 100vh;
  overflow: hidden;
}

.column {
  flex: 1;
  height: 100vh;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
}

.wrapper {
  display: block;
  width: 100%;
}

期望: 当将鼠标悬停在其上时,每个 .column 就会独立滚动。

实际情况(仅在Safari): 没有滚动——只是最顶端和最底端边缘的橡皮筋。Chrome可以正确工作。

我已经尝试过的做法,均未能解决Safari:

  • flex: 1; min-height: 0 应用于滚动子元素,而不是显式高度
  • 在滚动子元素上应用 position: absolute; inset: 0
  • 在列上应用 will-change: scroll-position
  • transform: translateZ(0) 从所有sticky子元素中移除
  • 在内部元素上应用 touch-action: pan-y
  • 使用 overflow-y: scroll 代替 auto
  • -webkit-overflow-scrolling: touch

根本原因(部分):min-height: 100% 加到 .wrapper 上会悄悄地把 scrollHeight 限制为等于 clientHeight,从而消除了滚动范围。移除它后,列1(内容足够多)就能滚动。但内容较少的列在Safari中仍然表现为仅橡皮筋的滚动行为,且为何Safari与 Chrome在此处对scrollHeight的计算方式不同,这个根本问题仍不清楚。

问题: 是否存在一种可靠、得到广泛支持的CSS模式,用于在 display: flex 全高度布局中实现独立滚动的列,并且在Safari中可用?是否有人找到明确的修复方法?

环境: Safari 17 / macOS Sonoma。可在桌面Safari和 iOS Safari上复现。

解决方案

所以对于一个div在使用百分比单位时填充高度,你必须从body标签开始,逐层为每一级都指定高度。

在这个示例中,我试图更清晰地可视化你的做法,并且在每一列上也添加了 flex-grow

在我这边,在Safari 17 / Monterey上没有看到橡皮滚动。

body {
  margin: 0;
  padding: 0;
  min-height: 100%;
}

.container {
  display: flex;
  height: 100vh;
  overflow: hidden;
}

.column {
  flex-grow: 1;
  overflow-y: auto;
  overflow-x: hidden;
  -webkit-overflow-scrolling: touch;
  min-height: 100%;
}

.col-1 {
  background-color: red;
}

.col-2 {
  background-color: blue;
}

.col-3 {
  background-color: yellow;
}

.wrapper {
  width: 100%;
}

.fill {
  display: block;
  width: calc(100% - 30px);
  height: 300px;
  margin: 15px auto 15px auto;
  border: 1px solid black;
}
<div class="container">
  <div class="column col-1">
    <div class="wrapper">
      <!-- Filler content -->
      <div class="fill"></div>
      <div class="fill"></div>
      <div class="fill"></div>
      <div class="fill"></div>
      <div class="fill"></div>
      <div class="fill"></div>
    </div>
  </div>
  <div class="column col-2">
    <!-- Filler content -->
    <div class="fill"></div>
  </div>
  <div class="column col-3">
    <div class="wrapper">
      <!-- Filler content -->
      <div class="fill"></div>
      <div class="fill"></div>
      <div class="fill"></div>
      <div class="fill"></div>
      <div class="fill"></div>
      <div class="fill"></div>
    </div>
  </div>
</div>
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章