为什么表格布局:固定会影响父元素的宽度?

时间:2018-08-11 15:39:55

标签: html css css3 html-table

有人可以解释为什么我的divtable-layout:fixed将其父元素(在这种情况下为body)的宽度更改为100%而不是100%因为它的位置?

body {
  border: 2px solid red;
  height: 100vh;
  margin:0;
  padding: 0;
  position: absolute;
}

.c{
  display: table;
  width: 80%; /* Any percentage value different from 0 */
  table-layout:fixed;
  outline: 2px solid blue;
}
<div class="c">d</div>

正如您在上方看到的,添加table-layout:fixed会强制正文变为全宽,并且width上的百分比div相对于{的width {1}}!

以下代码段不是这种情况,该行为在某种程度上是合理且直观的:

body
body {
  border: 2px solid red;
  height: 100vh;
  margin:0;
  padding: 0;
  position: absolute;
}

.c{
  display: table;
  width: 80%;
  /* table-layout:fixed; */
  outline: 2px solid blue;
}

<div class="c">d</div>如何影响在这种情况下定位的父元素?


请注意,将像素值与table-layout:fixed一起使用会产生逻辑结果:

width
body {
  border: 2px solid red;
  height: 100vh;
  margin:0;
  padding: 0;
  position: absolute;
}

.c{
  display: table;
  width: 200px; 
  table-layout:fixed;
  outline: 2px solid blue;
}

我们也可能会因这种奇怪行为而产生一些溢出:

<div class="c">d</div>
body {
 margin:0;
 position:relative;
 width:300px;
 border-top:20px solid green;
}

.container {
  border: 2px solid red;
  height: 100vh;
  position: absolute;
}

.c {
  display: table;
  width: 120%; 
  table-layout: fixed;
  outline: 2px solid blue;
  animation:change 2s linear infinite alternate;
}

@keyframes change {
  from{width:1%;}
  to {width:150%}
}

3 个答案:

答案 0 :(得分:6)

看起来像you're not the first to bring this up。不过,您可能是第二位。

要清楚,这是两个问题的组合:

  1. The width of an absolutely positioned element is shrink-to-fit.以某种方式确定了“缩小以适合”宽度,该宽度与弃置元素的包含块所允许的宽度一样。 (绝对定位的body的包含块是初始包含块。)

  2. A percentage width on an element whose containing block depends on its contents for auto sizing results in undefined behavior.

第2个问题是pretty easy to write off

  

实现同意不要重复计算两个元素的宽度。

body的大小使用缩小至适合大小,然后将表格设置为该宽度的80%,body的大小为"not computed again"。唯一的“不确定性”是规范不需要或不允许,或者实际上不在乎实现要做什么。

因此,问题接着归结为:为什么在确定#2中表的大小之前,在#1中“缩小以适应”会产生“尽可能宽”的结果。规范描述了收缩元素的收缩配合:

  

[...] 大致:通过设置内容的格式来计算首选宽度,而不是在出现明显换行符的地方不换行,并计算首选最小宽度,例如,尝试所有可能的换行符。 CSS 2.1并未定义确切的算法。第三,计算可用宽度:通过将“ left”(在情况1中)或“ right”(在情况3中)设置为0,然后通过求解“ width”来找到。

     

则收缩至适配宽度为:min(max(首选最小宽度,可用宽度),首选宽度)。

但这不能告诉我们为什么,甚至那个,固定布局表的首选宽度是“其包含块所允许的宽度”。 css-sizing-3和css-tables-3都没有包含答案。

根据David Baron(来自同一线程),他在壁虎上工作:

  

固定版式表格将内在最大内容内联大小报告为无限。

(请注意,“最大内容在线尺寸”与“首选宽度”含义相同)

所以这就是我们的答案。固定布局表的无限制最大内容内联大小是导致此表的绝对定位父级被拉伸到其自身包含块(初始包含块)所允许的宽度的原因,这与自动布局表相反。

而且,至少就目前而言,这已经接近我的官方消息了,因为仅阅读css-sizing-3很难得出相同的结论,而且我不确定David的声明仅基于Gecko的行为,所有实现的行为或指定的行为。

答案 1 :(得分:1)

这是我基于上述问题的解释,因此根据对“官方资源”的赏金要求,可以将其视为推测

  

应用表格布局:固定时,内容不再决定布局,而是浏览器使用表格第一行中定义的宽度来定义列宽。如果第一行没有宽度,则无论单元格内的内容如何,​​列的宽度都会在表格中平均分配。

     

为了使fixed的值生效,表的宽度必须设置为auto以外的值(width属性的默认值)... source

一旦应用table-layout:fixed;且父容器没有任何设置宽度并且其自身宽度以百分比设置,它将扩展其父容器(无论该容器是body / div / etc)到100%,并采用相对于父级的指定宽度(在这种情况下为80%)。

之所以会这样做,是因为其默认目的是设置 width ,以确保其列宽均匀分布,而不管是否有列。如果它们不是任何列,则将元素视为一列。为此,它仍然需要其宽度相对于其父对象(当其自身的宽度设置为%时)。

由于table-layout:fixed虽然没有在CSS中设置,但没有定义宽度,因此未应用,因此table-layout:auto被应用为默认值:

body {
  border: 2px solid red;
  height: 100vh;
  margin: 0;
  padding: 0;
  position: absolute;
}

.c {
  display: table;
  table-layout: fixed;
  /* width: 80%; */
  outline: 2px solid blue;
}
<div class="c">d</div>

现在让我们设置宽度:

body {
  border: 2px solid red;
  height: 100vh;
  margin: 0;
  padding: 0;
  position: absolute;
}

.c {
  display: table;
  table-layout: fixed;
  width: 80%;
  outline: 2px solid blue;
}
<div class="c">d</div>

答案 2 :(得分:-2)

在第二个示例中,

body {
  border   : 2px solid red;
  height   : 100vh;
  margin   : 0;
  padding  : 0;
  position : absolute;

}

.c {
  display : table;
  width   : 80%;
  outline : 2px solid blue;
  /* table-layout : fixed; */
}

您已经完全确定了身体的位置,因此它没有正常流动,并且不会影响其.c子代的位置或尺寸。

因此.c的宽度并不像您最初预期的那样占主体的80%。

但是,您可以使用像素或vw等单位来设置.c的宽度,结果将更加直观,例如this

.c {
  display : table;
  width   : 80vw; 
  outline : 2px solid blue;
  /* width : 80%;  */
  /* table-layout : fixed; */
}

类似地,当您使用table-layout:fixed;时,浏览器使用一种算法来计算表格的宽度,这类似于使用像素或vw等单位来计算表格的宽度。

quote from the W3C spec

  

17.5.2.1固定的表格布局使用此(快速)算法,表格的水平布局不取决于单元格的内容...