pre/code 带有水平滚动条的元素破坏了 Firefox 上的弹性布局

pre/code element with horizontal scrollbar breaks the flex layout on Firefox

在我基于 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>

您在这里需要做的就是设置代码块的父元素 <pre>,在本例中 <div class="c">overflow: hidden

.c {
  background: #971;
  flex: 1;
  overflow: hidden;
}

.c 是一个块元素,它占据了它到达这里的所有 space,而不允许此规则集溢出。

pre 由于子项溢出其父项,因为它占用更多 space 因为它的内容,所以 overflow: auto 将被设置为滚动到这里,导致滚动区域出现在内部 pre - element.

示范:

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>

您只需在弹性项目 .c 上设置 min-width:0。查看我的了解更多。

背景故事:flexbox 规范引入了一个新的大小调整功能,min-width: auto,它强制 flex 项目 至少 与其最小内容宽度一样大 --它们的内容需要的最小宽度,以避免溢出。目前,Firefox 是唯一实现此功能的浏览器,这就是为什么您只能在那里看到它的原因。

如果您想禁用此行为,只需给弹性项目 min-width:0

(您也可以在 flex 项目上设置 overflow:hidden,如此处其他答案中所述,但这太过分了。这只会通过强制 min-width:auto 解析为 0 来使您受益min-width:auto 定义中的特殊情况。缺点是 overflow:hidden 强制浏览器做额外的工作来管理 flex 项目的不可见可滚动区域,并且这在内存和性能方面的成本非零,所以最好避免它,除非你实际上在 flex 项目上 using 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>