滚动位置受页面元素内部布局更改的影响(Chrome)?

ole*_*enb 5 html css google-chrome flexbox

https://jsfiddle.net/gxas8h7L/5/

运行小提琴并向下滚动,直到页面顶部与红色子框之一相交。观察滚动位置随着“世界”定期切换而变化。(看起来整个页面向上/向下跳跃)

切换不会影响父级高度。这严格来说是“组件内部”的更改。

如果灰色框绝对定位,效果仍然存在。

罪魁祸首似乎是红色框内的项目的中心对齐(flex)(align-items: center;)似乎chrome确实更喜欢“你好”不移动。

这是 Chrome 的 bug 还是一些奇怪的 css 功能?

在 Firefox 中不会发生。

在 Chrome 版本 85.0.4183.102(官方版本)(64 位)Linux 中测试

setInterval(
    () => {
        $(".foo").toggle()
    console.log(document.scrollingElement.scrollTop)
}, 800)
Run Code Online (Sandbox Code Playgroud)
#c {
  height: 3000px;
}

#x1 {
  top: 10px;
}
#x2 {
  top: 130px;
}
#x3 {
  top: 260px;
}

.item {
  /* position: absolute; */
  left: 0px;
  height: 100px;
  width: 400px;
  background-color: gray;
  padding: 4px;
  margin-top: 10px;
}

.bar {
  display: flex;
  align-items: center;
  height: 70px;
  background-color: red;
}

.elem {
  border: 2px solid black;
  margin-left: 2px;
}
Run Code Online (Sandbox Code Playgroud)
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="c">
  <div id="x1" class="item">
    <div class="bar">
      <div class="elem">
        <div>hello</div>
        <div class="foo">world</div>
      </div>
    </div>
  </div>
  <div id="x2" class="item">
    <div class="bar">
      <div class="elem">
        <div>hello</div>
        <div class="foo">world</div>
      </div>
    </div>
  </div>
  <div id="x3" class="item">
    <div class="bar">
      <div class="elem">
        <div>hello</div>
        <div class="foo">world</div>
      </div>
    </div>
  </div>
</div>
Run Code Online (Sandbox Code Playgroud)

vbr*_*aun 2

基本规则是:如果滚动内容的子元素的 css 框改变了其高度并且当前与视口的上边框相交,则调整滚动位置以使该框的上边框保持在当前位置。

这是有意义的,因为您希望增量加载的内容向下推页面,而不是进一步向上推页面标题。

Firefox(88.0 Linux 64 位)也这样做,唯一的警告是,如果框反复更改其高度,那么在第 10 次更改后它将被忽略。

该框是滚动内容的直接子项还是间接子项并不重要。

影响此行为的 css 属性很少,我只知道两个:

  • display: none(也许并不奇怪,因为没有计算盒子的高度)
  • flex-direction: column-reverse在容器上(而且必须是弹性盒)。在这种情况下,行为是垂直反转的,与视口底部边框相交的子项的 css 框高度变化会导致滚动调整。