使用 flexbox 的 Google Chrome 视口锚定扩展方向
Posted
技术标签:
【中文标题】使用 flexbox 的 Google Chrome 视口锚定扩展方向【英文标题】:Google Chrome viewport-anchored expand direction with flexbox 【发布时间】:2017-12-03 05:34:42 【问题描述】:在 Google Chrome 中存在一个问题,当元素放置在具有 space-between
或 center
对齐内容的 相邻 flex 项目的 flexbox 容器中时,元素相对于视口在不同方向展开/折叠.
这在 Firefox、IE11、Edge 或 Safari 中不是问题,因为元素总是向下扩展。
我很好奇:
Chrome 的行为是否遵循某些规范?如果有,是哪一个? 如果不是,那为什么要在 Chrome 中完成呢? (恕我直言,点击触发器随机消失在屏幕外是可怕的用户体验。) 能否以某种方式修改或禁用 Chrome 的行为?例如。通过 CSS 或元标记?更新 1:如果可能,我已提交 issue #739860 on chromium bug tracker 寻求 Chromium 开发人员的见解/解释。
以下是插入的两个示例。可以在这支笔中找到描述该问题的完整测试套件:https://codepen.io/jameswilson/full/xrpRPg/ 在此示例中我选择使用 slideToggle 以便展开/折叠运动具有动画效果并且肉眼可见。细节标签也会发生同样的行为,但还没有跨浏览器支持,而且展开/折叠太卡了。
示例 1:Chrome 对两端对齐的 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>
示例 2:Chrome 的中心对齐 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>
【问题讨论】:
听起来像是最近实现的scroll anchoring 功能。如您所见,可以通过容器或文档正文上的overflow-anchor: none
选择退出。
@wOxxOm ++ 你完全正确。将overflow-anchor: none
添加到.flexcontainer
可以解决此问题。如果您将其转换为答案,我将奖励您积分。你也是通过 chromium tracker 上的 bug 来到这里的吗?
不,这么简单的事情不需要积分,是的,我确实来自错误跟踪器。
我明白并感谢它,但这是正确的答案,因此需要将其作为答案归档,以便将问题标记为已回答和接受。 ;) 如果不感兴趣,我可以做,我会等一下。
【参考方案1】:
将此代码添加到您的弹性容器中:
overflow-anchor: none
这将禁用 Chrome 中称为“滚动锚定”的功能,该功能会导致框向上扩展 (revised codepen)。
在 Chrome 中,展开框的向上/向下方向由视口中的滚动位置决定,而不是布局本身。
Chrome 对这种行为采取了一种独特的方法来改善用户体验。
基本上,它们将 DOM 元素绑定到当前滚动位置。屏幕上这个特定(“锚”)元素的移动将决定对滚动位置的调整(如果有的话)。
他们将这种方法称为“滚动锚定”。该算法在此页面上进行了说明: https://github.com/WICG/ScrollAnchoring/blob/master/explainer.md
这种行为目前是 Chrome 独有的,但 Google is pushing for standardization.
根据滚动锚定文档,将overflow-anchor: none
应用于适当的元素将禁用滚动锚定调整。
更多信息:
https://github.com/WICG/ScrollAnchoring/blob/master/explainer.md https://bugs.chromium.org/p/chromium/issues/detail?id=739860 https://hacks.mozilla.org/2019/03/scroll-anchoring-in-firefox-66/ Changing CSS flex order causes scrolling【讨论】:
这似乎也会影响不是display: flex
的容器。任何线索何时开始在 Chrome 中发生?据说他们支持该功能有一段时间了,但最近才注意到它。以上是关于使用 flexbox 的 Google Chrome 视口锚定扩展方向的主要内容,如果未能解决你的问题,请参考以下文章
Google发布flexbox-layout 能替代FlowLayout吗
CSS3 Flexbox:显示:box vs. flexbox vs. flex
CSS3 Flexbox:显示:box vs. flexbox vs. flex