带有 flexbox 的 Google Chrome 视口锚定扩展方向 [英] Google Chrome viewport-anchored expand direction with flexbox

查看:13
本文介绍了带有 flexbox 的 Google Chrome 视口锚定扩展方向的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Google Chrome 中存在一个问题,当放置在具有 space-between相邻 flex 项目的 flexbox 容器中时,元素会相对于视口在不同方向展开/折叠> 或 center 对齐的内容.

这在 Firefox、IE11、Edge 或 Safari 中不是问题,因为元素总是向下扩展.

我很好奇:

  • Chrome 在此处的行为是否遵循某些规范?如果有,是哪一个?
  • 如果不是,那为什么要在 Chrome 中完成?(恕我直言,点击触发器随机消失在屏幕外的用户体验很糟糕.)
  • 能否以某种方式修改或禁用 Chrome 的行为?例如.通过 CSS 还是元标记?

更新 1:我已提交

$('button').click(function() {$(this).next().slideToggle();})

body {边距:30px;字体系列:无衬线;}在旁边,除了div,概括,主要的,按钮,详情 p,按钮 + p {背景:RGBA(0,0,0,.09);边界:无;填充:20px;边距:0;}.flexcontainer {显示:弹性;}在旁边 {弹性:1;位置:相对;最大宽度:25%;背景:薄荷糖;显示:弹性;弹性方向:列;位置:相对;}旁边的空间之间{对齐内容:间隔;}一边.中心{对齐内容:居中;}主要的 {弹性:3;位置:相对;最大宽度:75%;背景:aliceblue;垂直对齐:顶部;高度:100%;}主要 >* + * {边距顶部:20px;}按钮 + p {显示:无;}

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script><section class="flexcontainer"><aside class="space-between"><div>顶部侧边栏</div><div>底部边栏</div></一边><主要><div><button>slideToggle</button><p>其他浏览器:始终向下扩展.<br>Chrome:应始终向下扩展,因为顶部边栏始终可见.</p>

<div><button>slideToggle(通常向下展开)</button><p>其他浏览器:始终向下扩展.<br>Chrome:应该向下扩展,同时底部边栏和顶部边栏都可见.但是,如果您向下滚动到足够远的位置,顶部侧边栏会在屏幕外,则会向上扩展.</p>

<div><button>slideToggle(通常向下展开)</button><p>其他浏览器:始终向下扩展.<br>Chrome:应该向下扩展,同时底部边栏和顶部边栏都可见.但是,如果您向下滚动到足够远的位置,顶部侧边栏会在屏幕外,则会向上扩展.</p>

</main></section>

Ex 2:Chrome 对居中对齐的 flexbox 的展开/折叠行为

$('button').click(function() {$(this).next().slideToggle();})

body {边距:30px;字体系列:无衬线;}在旁边,除了div,概括,主要的,按钮,详情 p,按钮 + p {背景:RGBA(0,0,0,.09);边界:无;填充:20px;边距:0;}.flexcontainer {显示:弹性;}在旁边 {弹性:1;位置:相对;最大宽度:25%;背景:薄荷糖;显示:弹性;弹性方向:列;位置:相对;}旁边的空间之间{对齐内容:间隔;}一边.中心{对齐内容:居中;}主要的 {弹性:3;位置:相对;最大宽度:75%;背景:aliceblue;垂直对齐:顶部;高度:100%;}主要 >* + * {边距顶部:20px;}按钮 + p {显示:无;}

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script><section class="flexcontainer"><aside class="center"><div>中心侧边栏</div></一边><主要><div><button>slideToggle(通常向下扩展)</button><p>其他浏览器:始终向下扩展.<br>Chrome:通常向下扩展.当容器的顶部边缘滚动出视口时在两个方向上扩展.</p>

<div><button>slideToggle</button><p>其他浏览器:始终向下扩展.<br>Chrome:通常向下扩展.当容器的顶部边缘滚动出视口时在两个方向上扩展.</p>

<div><button>slideToggle(通常向下扩展)</button><p>其他浏览器:始终向下扩展.<br>Chrome:通常向下扩展.当容器的顶边滚出视口时,在两个方向上展开,但当中心侧边栏滚出视口时又恢复向下展开.</p>

</main></section>

解决方案

将此代码添加到您的 flex 容器:

这将禁用 Chrome 中称为滚动锚定"的功能,该功能会导致框向上扩展 (修改代码笔).

<小时>

在 Chrome 中,扩展框的向上/向下方向由视口中的滚动位置控制,而不是布局本身.

Chrome 对这种行为采取了独特的方法,以改善用户体验.

基本上,它们将 DOM 元素绑定到当前滚动位置.这个特定(锚点")元素在屏幕上的移动将决定对滚动位置的调整(如果有的话).

他们称这种方法为滚动锚定".该算法在此页面上进行了解释:https://github.com/WICG/ScrollAnchoring/blob/master/explainer.md

此行为目前是 Chrome 独有的,但 Google 正在推动标准化.

根据滚动锚定文档,将 overflow-anchor: none 应用于适当的元素将禁用滚动锚定调整.

更多信息:

There is an issue in Google Chrome where elements expand/collapse in different directions relative to the viewport when placed inside a flexbox container with an adjacent flex item having space-between or center justified content.

This is not a problem in Firefox, IE11, Edge, or Safari as the elements always expand downward.

I'm curious:

Update 1: I've filed issue #739860 on chromium bug tracker seeking insight/explanation from Chromium devs, if possible.


Here are two examples inserted below. The full test suite describing the problem can be found in this pen: https://codepen.io/jameswilson/full/xrpRPg/ I've chosen to use slideToggle in this example so that the expand/collapse motion is animated and visible to the eye. The same behavior happens with the details tag, but cross-browser support is not there yet, and the expand/collapse is too janky.

Ex 1: Chrome's expand/collapse behavior for space-between justified flexbox

$('button').click(function() {
  $(this).next().slideToggle();
})

body {
  margin: 30px;
  font-family: sans-serif;
}
aside,
aside div,
summary,
main,
button,
details p,
button + p {
  background: rgba(0,0,0,.09);
  border: none;
  padding: 20px;
  margin: 0;
}

.flexcontainer {
  display: flex;
}
aside {
  flex: 1;
  position: relative;
  max-width: 25%;
  background: mintcream;

  display: flex;
  flex-direction: column;
  position: relative;
}
aside.space-between {
  justify-content: space-between;
}
aside.center {
  justify-content: center;
}

main {
  flex: 3;
  position: relative;
  max-width: 75%;
  background: aliceblue;
  vertical-align: top;
  height: 100%;
}
main > * + * {
  margin-top: 20px;
}

button + p {
  display: none;
}

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<section class="flexcontainer">
  <aside class="space-between">
    <div>Top Sidebar</div>
    <div>Bottom Sidebar</div>
  </aside>
  <main>
    <div>
      <button>slideToggle</button>
      <p>Other browsers: always expands downward.<br>
        Chrome: Should always expand downward because Top Sidebar is always visible.</p>
    </div>

    <div>
      <button>slideToggle (usually expands down)</button>
      <p>Other browsers: always expands downward.<br>
        Chrome: Should expand downward while Bottom Sidebar and Top Sidebar are both visible. But will expand upward if you scroll down far enough so that Top Sidebar is off-screen.</p>
    </div>
    
    <div>
      <button>slideToggle (usually expands down)</button>
      <p>Other browsers: always expands downward.<br>
        Chrome: Should expand downward while Bottom Sidebar and Top Sidebar are both visible. But will expand upward if you scroll down far enough so that Top Sidebar is off-screen.</p>
    </div>
  </main>
</section>

Ex 2: Chrome's expand/collapse behavior for center justified flexbox

$('button').click(function() {
  $(this).next().slideToggle();
})

body {
  margin: 30px;
  font-family: sans-serif;
}
aside,
aside div,
summary,
main,
button,
details p,
button + p {
  background: rgba(0,0,0,.09);
  border: none;
  padding: 20px;
  margin: 0;
}

.flexcontainer {
  display: flex;
}
aside {
  flex: 1;
  position: relative;
  max-width: 25%;
  background: mintcream;

  display: flex;
  flex-direction: column;
  position: relative;
}
aside.space-between {
  justify-content: space-between;
}
aside.center {
  justify-content: center;
}

main {
  flex: 3;
  position: relative;
  max-width: 75%;
  background: aliceblue;
  vertical-align: top;
  height: 100%;
}
main > * + * {
  margin-top: 20px;
}

button + p {
  display: none;
}

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<section class="flexcontainer">
  <aside class="center">
    <div>Center Sidebar</div>
  </aside>
  <main>

    <div>
      <button>slideToggle (usually expands downwards)</button>
      <p>Other browsers: always expands downward.<br>
        Chrome: Usually expands downwards. Expands in both directions when the top-edge of the container scrolls out of the viewport.</p>
    </div>

    <div>
      <button>slideToggle</button>
      <p>Other browsers: always expands downward.<br>
        Chrome: Usually expands downwards. Expands in both directions when the top-edge of the container scrolls out of the viewport.</p>
    </div>

    <div>
      <button>slideToggle (usually expands downwards)</button>
      <p>Other browsers: always expands downward.<br>
        Chrome: Usually expands downwards. Expands in both directions when the top-edge of the container scrolls out of the viewport, but then resumes expanding downwards again when Center Sidebar scrolls out of view.</p>
    </div>
  </main>
</section>

解决方案

Add this code to your flex container:

This will disable a feature in Chrome known as "scroll anchoring", which is causing the upward expansion of boxes (revised codepen).


In Chrome, the upward / downward direction of expanding boxes is governed by the scroll position in the viewport, not the layout itself.

Chrome takes a unique approach to this behavior for the purpose of improving the user experience.

Basically, they bind a DOM element to the current scroll position. The movement of this particular ("anchor") element on the screen will determine an adjustment, if any, to the scroll position.

They call this approach "Scroll Anchoring". The algorithm is explained on this page: https://github.com/WICG/ScrollAnchoring/blob/master/explainer.md

This behavior is currently unique to Chrome, but Google is pushing for standardization.

In accordance with the Scroll Anchoring documentation, applying overflow-anchor: none to the appropriate element(s) will disable scroll anchoring adjustments.

More information:

这篇关于带有 flexbox 的 Google Chrome 视口锚定扩展方向的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆