带有水平滚动条的 pre/code 元素破坏了 Firefox 上的 flex 布局
Posted
技术标签:
【中文标题】带有水平滚动条的 pre/code 元素破坏了 Firefox 上的 flex 布局【英文标题】:pre/code element with horizontal scrollbar breaks the flex layout on Firefox 【发布时间】:2015-05-07 22:35:24 【问题描述】:在我的基于 flexbox 的布局中,我可能有一个 <pre><code></code></pre>
元素(以及其他元素)。因为它的内容可能比容器宽,所以我把它设为overflow-x:auto
。
在 Chrome 上完美运行:
但它在 Firefox 上坏了:
如果没有硬编码的尺寸,我该如何解决这个问题?
div,pre
padding: 5px;
color: white;
.m
background: #222;
display: flex;
.l, .r
background: #143;
flex: 0 0 100px;
.c
background: #971;
flex: 1;
pre
white-space: pre;
word-wrap: normal;
overflow-x: auto;
<div class=m>
<div class=l>this must be 100px wide</div>
<div class=c>this must take the remaining space</div>
<div class=r>this must be 100px wide</div>
</div>
<div class=m>
<div class=l>this must be 100px wide</div>
<div class=c>
<pre><code>The following line of code is long:
This is the long line of code the previous line of code was referring to (no, it can't be 72 col, sorry for the inconvenience)</code></pre>
Some other content in the c column.</div>
<div class=r>this must be 100px wide</div>
</div>
【问题讨论】:
不确定为什么 Chrome 和 Firefox 的行为不同,但如果可以将overflow-x: auto; overflow-y: hidden;
应用于中间列(具有.c
类),则可以解决此问题。
@HashemQolami 这不是我想要的(中间列可能包含其他元素)。但这可能有助于为 Firefox 制定解决方法。
这真的很奇怪,如果你看到这里:jsfiddle.net/roj0a54k/1 <code>
元素是一个内联元素。如果你将它设置为阻止并设置一个奇怪的max-width
像 10px 它似乎在 Firefox 中工作。
【参考方案1】:
您只需在弹性项目.c
上设置min-width:0
。请参阅我的answer on this similar question 了解更多信息。
背景故事:flexbox 规范引入了一个新的大小调整特性min-width: auto
,它强制弹性项目至少与它们的最小内容宽度一样大——它们的内容需要的最小宽度, 避免溢出。目前,Firefox 是唯一实现此功能的浏览器,这就是为什么您只能在那里看到它。
如果你想禁用这个行为,只需给弹性项目min-width:0
。
(您也可以在弹性项目上设置overflow:hidden
,如此处其他答案中所述,但这太过分了。这只会通过@987654329 中的特殊情况强制min-width:auto
解析为0 来使您受益@定义。缺点是overflow:hidden
也迫使浏览器做额外的工作来管理弹性项目的不可见滚动区域,这在内存和性能方面有非零成本,所以最好避免它,除非你真的在弹性项目上使用 overflow:hidden
。而你没有,所以最好避免它。)
div,pre
padding: 5px;
color: white;
.m
background: #222;
display: flex;
.l, .r
background: #143;
flex: 0 0 100px;
.c
background: #971;
flex: 1;
min-width: 0;
pre
white-space: pre;
word-wrap: normal;
overflow-x: auto;
<div class=m>
<div class=l>this must be 100px wide</div>
<div class=c>this must take the remaining space</div>
<div class=r>this must be 100px wide</div>
</div>
<div class=m>
<div class=l>this must be 100px wide</div>
<div class=c>
<pre><code>The following line of code is long:
This is the long line of code the previous line of code was referring to (no, it can't be 72 col, sorry for the inconvenience)</code></pre>
Some other content in the c column.</div>
<div class=r>this must be 100px wide</div>
</div>
【讨论】:
顺便说一句,本着 css-tricks 的精神,有人应该制作一个很好的页面来解释真正的 flex 模型,但足够完整和正确......【参考方案2】:您需要在这里做的就是将代码块的父元素设置为<pre>
,在本例中将<div class="c">
设置为overflow: hidden
.c
background: #971;
flex: 1;
overflow: hidden;
.c
是一个块元素,它占用了它在此处获得的所有空间,而不允许此规则集溢出。
pre
因为子元素由于其内容占用了更多空间而溢出其父元素,因此overflow: auto
将在此处设置为滚动,从而导致滚动区域出现在内部pre
- 元素上。
演示:
div,pre
padding: 5px;
color: white;
.m
background: #222;
display: flex;
.l, .r
background: #143;
flex: 0 0 100px;
.c
background: #971;
flex: 1;
overflow: hidden;
pre
white-space: pre;
word-wrap: normal;
overflow-x: auto;
<div class=m>
<div class=l>this must be 100px wide</div>
<div class=c>this must take the remaining space</div>
<div class=r>this must be 100px wide</div>
</div>
<div class=m>
<div class=l>this must be 100px wide</div>
<div class=c>
<pre><code>The following line of code is long:
This is the long line of code the previous line of code was referring to (no, it can't be 72 col, sorry for the inconvenience)</code></pre>
Some other content in the c column.</div>
<div class=r>this must be 100px wide</div>
</div>
【讨论】:
其他面临同样问题的用户请注意:如果您的基于 flex 的布局更深,您可能需要将overflow:hidden
应用于其他父元素。
overflow:hidden
太过分了——你真的只想要min-width: 0
。这里的问题在于新的默认min-width:auto
,它在弹性项目上有点神奇(Chrome 还没有实现)。 overflow:hidden
恰好可以工作,因为它使 min-width:auto
解析为 0;但它也有其他副作用。你想要的只是min-width:0
,而不是其他副作用。
拜托,这个答案不应该被否决。这是我们能找到的最佳解决方案,直到有 Mozilla 内部知识的人进来。
@dhollbert 很有趣,不知道这个。我已经在想overflow: hidden
正在以“副作用”的形式实现解决方案,同时在这种情况下做了更多不必要的事情。感谢您清除此问题以上是关于带有水平滚动条的 pre/code 元素破坏了 Firefox 上的 flex 布局的主要内容,如果未能解决你的问题,请参考以下文章