内容更改时 Flexbox 高度不更新

Posted

技术标签:

【中文标题】内容更改时 Flexbox 高度不更新【英文标题】:Flexbox height not updating when content changes 【发布时间】:2014-06-21 20:33:02 【问题描述】:

chrome 中的 flexbox 似乎存在影响可变高度列的问题。当这些列的内容发生变化时,列应该调整大小,但它不会

我在这里创建了一个 JS fiddle - http://jsfiddle.net/KVQTd/2/

只需点击“删除内容按钮”即可了解我的意思。

这是使用 flexbox 创建列以证明没有其他原因导致它的最简单示例。

.wrapper
    display: flex;
    align-items: stretch;


.column1
    flex: 1;


.column2
    flex: 1;

我很确定这是 Chrome 中的一个错误,因为当您进入开发者工具并关闭再打开 flex 时,它会正确计算高度。

我在这里提交了一个错误报告 - https://code.google.com/p/chromium/issues/detail?id=369869&thanks=369869&ts=1399226675 -

...但是我没有时间等待新版本的 Chrome 发布,所以我希望有人能够想出一个聪明的解决方案。也许某种 javascript 会监视内部内容的高度并进行调整,从而强制重新计算 flexbox 高度?

【问题讨论】:

这是 chrome 中的一个已知错误,目前无法治愈,除非刷新 谢谢,在发布错误报告之前,我在 Google 上非常努力地搜索,看看是否有其他人注意到了,但显然我没有在寻找正确的东西。如果这是一个已知的错误,那么他们正在拖延修复它。我在最近几个版本中都知道它,但只是刚刚开始尝试找到解决方案。 由于您已经使用了 javaScript,我们可以提供一种无需重新加载即可强制刷新的方法,更像是内容的重排。请参阅下面的答案和演示,以检查这是否可行并适合您。 现在对我来说似乎可以正常工作(Chrome 35)。 【参考方案1】:

为了在 Chrome 中工作,它需要刷新或某种回流。 DEMO

如果您编写脚本强制重新计算主容器,那么您就有了一些可行的方法。 (这看起来像是 Opera 的一些非常老的 bug)

为了做到这一点,我们可以从静态位置切换到相对位置,并使用伪来插入一些内容。

CLASS 包装器成为一个 ID,以便通过 JavaScript 轻松选择它

<div id="wrapper">
    <div class="column1">This column Has some content</div>
    <div class="column2">This column also has some content
        <div id="contentToHide">
            <p>Sed egestas, ante et vulputate volutpat, eros pede semper est, vitae luctus metus libero eu augue. Morbi purus libero, faucibus adipiscing, commodo quis, gravida id, est. Sed lectus. Praesent elementum hendrerit tortor. Sed semper lorem at felis. Vestibulum volutpat, lacus a ultrices sagittis, mi neque euismod dui, eu pulvinar nunc sapien ornare nisl. Phasellus pede arcu, dapibus eu, fermentum et, dapibus sed, urna.</p>
        </div>
    </div>
</div>
<button id="removeButton">Remove Content</button>
<br/>
<button id="addButton">Add Content</button>

javaScript 更新

document.getElementById('removeButton').addEventListener("click", function (event) 
    document.getElementById('contentToHide').classList.add("hidden");
    document.getElementById('wrapper').classList.add("prelative");
);

document.getElementById('addButton').addEventListener("click", function (event) 
    document.getElementById('contentToHide').classList.remove("hidden");
    document.getElementById('wrapper').classList.remove("prelative");
);

CSS 更新:

#wrapper 
    display: flex;
    width: 400px;
    margin-bottom: 30px;

.column1 
    padding: 10px;
    background: #DDD;

.column2 
    padding: 10px;
    background: #EEE;
    width:50%;

#contentToHide.hidden 
    display: none;

.prelative 
    position:relative;

div:before 
    content:attr(class);
    left:-9999px;
    position:absolute;


实际上,对于 .hidden 和 pseudo 你可以这样做:

#contentToHide.hidden ,
div:before 
    content:attr(class);
    left:-9999px;
    position:absolute;

【讨论】:

谢谢,在静态和相对定位之间切换似乎是诀窍。我的用例是一个选项卡系统,所以每次更改选项卡时我只需要更改列包装器的位置。很遗憾我必须这样做,但我相信他们会在某个时候解决它。 很好,但我认为只是获得回流的代码有点多......在我的情况下,我只需要为我所有的盒子制作一个选择器,然后给它们“位置” ": "static" 和 "position": "relative" 再次 - 但要小心,要真正触发回流,你必须给第二个调用一点超时,否则 webkit 认为他可以“优化”它,他不会t 进行回流,因为第二行会将其更改回默认状态下的正常状态.. @jebbie 然而,在 Chrome 行为得到修复之前,任何工作都应该没问题 :) psoition 开关和内容占用的资源很少,javascript 也不应该占用更多资源。关键是要唤醒 chrome :)【参考方案2】:

尝试为列设置height: 100%

【讨论】:

当我的一个 flexbox 重新渲染时,它会触发相邻的 flexbox 以不同的宽度重新渲染,即使内容是相同的。当我添加 height: 100% 时,我可以使用 Chrome 开发工具看到这些其他 div 中的更改并没有激活重新渲染。 chrome 48 发布后,我发现了这个错误。【参考方案3】:

这对我有用:

var elem = document.getElementById("myFlexbox");
elem.style.display='none';
elem.offsetHeight; // no need to store this anywhere, the reference is enough
elem.style.display='flex';

另见:How can I force WebKit to redraw/repaint to propagate style changes?

【讨论】:

dude:我只花了 2.5 个小时才弄清楚动态加载的内容会导致移动设备上的溢出。我从不知道你必须重置 flexbox!

以上是关于内容更改时 Flexbox 高度不更新的主要内容,如果未能解决你的问题,请参考以下文章

React Bootstrap flexbox 不会拉伸到内容高度

Internet Explorer 不尊重我的最小高度:100% 使用 flexbox

Bootstrap 4 导航栏和内容填充高度 flexbox

如何使用 flexbox 动态地进行 3 列 3 行的布局

带有 flexbox 的 css 正方形网格

Flexbox 和 vh 高度单位在 IE11 中不兼容吗?