带有水平滚动条的 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 &lt;code&gt; 元素是一个内联元素。如果你将它设置为阻止并设置一个奇怪的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】:

您需要在这里做的就是将代码块的父元素设置为&lt;pre&gt;,在本例中将&lt;div class="c"&gt; 设置为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 布局的主要内容,如果未能解决你的问题,请参考以下文章

查找导致在 Google Chrome 中显示水平滚动条的元素

设置滚动条的位置

如何在没有滚动条的 Tailwind 中创建可滚动元素

带有硒网络驱动程序的鼠标滚轮,在没有滚动条的元素上?

带有固定标题垂直滚动条的表格是IE11中的Flickr

如何让bootstrap表格自动出现水平滚动条