table 和 table-cell 上具有百分比宽度的奇怪行为

Strange behavior on table and table-cell with percentage width

我最近在这里偶然发现了一个问题,有人试图在他们的 headers 上获得适当的 line-behind 行为。像这样:

他们的实施在不同的 headers 中产生了不同的结果,因此产生了这个问题。通过对元素使用 table 而对 :before:after 使用 table-cell,实现非常奇怪。由此产生的行为对我来说非常令人惊讶。我在jsfiddle上做了个测试,你看看

你会看到我有两个类; ab,其中前者的宽度为 25%,后者的宽度为 40%。尽管如此,b 还是比 a 宽近 5 倍。将它们分别设置为 40% 和 45% 会使 ba 的两倍。这是完全出乎意料的行为,仅相差 5%。文本的长度似乎也会影响这一点。

我知道这个实现很糟糕,它会 "break"。但是,我想知道 为什么 它打破了它的工作方式。这对我来说毫无意义。

div {
  display: table;
  background: grey;
  margin: 10px 0;
}
div:before,
div:after {
  width: 25%;
  position: relative;
  content: '';
  border-top: 2px solid black;
  display: table-cell;
}
div.b:before,
div.b:after {
  width: 45%;
}
<div class="a">text</div>
<div class="a">some more text</div>

<div class="b">text</div>
<div class="b">some more text</div>

标准未指定自动表格布局,因此我建议不要使用这种百分比技巧,这可能会在某些浏览器上崩溃。

然而,大多数浏览器的行为似乎是这样的:

  • ::before::after 伪元素将占 table 的指定百分比。
  • 文本被包裹在一个具有文本宽度的匿名单元格中。那将代表伪元素留下的剩余百分比。
  • table 的宽度将由上述约束决定。

因此,如果您有 width: 25%,则文本将占用剩余的 50%

tablewidth = textwidth / 50% = 2 * textwidth
pseudowidth = 25% * tablewidth = 0.5 * textwidth

如果你有width: 40%,正文就拿剩下的20%

tablewidth = textwidth / 20% = 5 * textwidth
pseudowidth = 40% * tablewidth = 2 * textwidth

如果你有width: 45%,正文就拿剩下的10%。也就是说,如果文本相同,table 将相对于前一种情况加倍宽度。

tablewidth = textwidth / 10% = 10 * textwidth
pseudowidth = 45% * tablewidth = 4.5 * textwidth

当然,如果按上述计算的所需 table 宽度超过包含块,事情就会开始变得棘手。然后

  • table 将与包含块一样宽
  • 文本单元格将具有解析伪元素剩余百分比的结果宽度。这将小于文本的首选宽度,因此文本将换行。

    但是,文本单元格不会比文本所需的最小宽度窄。这通常是最长单词的宽度,但可能会因例如word-break: break-allwhite-space: nowrap.

  • 文本剩余的space将平均分配给伪元素

    如果剩余的 space 为负数,伪元素的宽度将为 0,并且 table 将增长(溢出包含块)以补偿它。