我试图在具有display:table-cell
属性的元素中使用浮动div,但我遇到了意外行为。
为什么第一列中的元素受到第二列中元素的影响(第一列中的a
突然向下移动)?有没有办法阻止这种行为?
.table {
display: table;
}
.cell {
display: table-cell;
}
.cell a {
padding: .5em;
border: .1em solid black;
}
.cell+.cell a {
float: left;
}

<div class='table'>
<div class='cell'>
<a>cell1</a>
</div>
<div class='cell'>
<a>cell2</a>
<a>cell2</a>
</div>
</div>
&#13;
答案 0 :(得分:4)
迷人的行为。我有几个理论。虽然我同意使用display: table-cell
似乎是随机的,但偶尔也会使用它,所以我会留在那里作为我的答案。如果我的答案过于复杂,我很抱歉;我会尝试简化它:
首先
要理解为什么元素被推下是一个理解垂直对齐如何为table-cell
s工作的问题:
vertical-align
,[{1}}和table-cell
应该使用的唯一top
属性值(请参阅this excellent css-tricks article) 。其他任何东西都是未定义的行为 - 意味着浏览器可以随心所欲地做任何事情,不同的浏览器可能会做不同的事情。这可能不是[永远......]我们想要的。
默认情况下,浏览器会提供所有middle
元素bottom
。因此,当您创建普通HTML td
时,您无需担心vertical-align: middle
属性。
另一方面,默认情况下,所有普通元素都有table
。带vertical-align
的元素上的这个值会导致我们可怕的未定义行为。
您正在使用默认情况下不会像表格一样的元素手动构建表格(这就是为什么当您不完全确定自己是什么时,您可能不应该使用vertical-align: baseline
这样做)。因此,您必须自己将所有表格的默认样式放在上面。这包括为display: table-cell
指定display: table-cell
属性。
那么为什么只有在我将元素浮动到一个单元格中时才会按下它?
同样,它是未定义的行为。当你不浮动时,这似乎不会引起问题;元素仍然能够智能地找到内部文本的基线并垂直对齐,以便它们出现在您期望的位置。当你漂浮在这里时,有两点需要注意:
1)请记住,float会从DOM的正常流中删除一个元素。这意味着其他元素包括元素的父元素,不能像通常那样与元素交互。
2)请记住
vertical-align: top|middle|bottom
是聪明的;他们可以动态地,垂直定位他们的孩子。
将这两者结合起来让我想到当你浮动这些元素时:
1)他们的.cell
父母正在失去文本在其中的位置。
2)它无法与基线所在的相邻单元正确通信 - 它只是使用其底边。
3)相邻小区正确地垂直对齐其内容与该基线,导致向下移动。
修复?
将table-cell
负责任地放在.cell
s:
vertical-align: middle
(.cell
标签也应该是.cell {
display: table-cell;
vertical-align: middle;
}
。这是一个更新的JSFiddle。问候。
答案 1 :(得分:1)
您在该规则.cell+.cell a
中有一个加号(即:adjacent siblings selector),删除它会按预期工作:
.cell a {
float: left;
}
答案 2 :(得分:1)
单元格的基线是第一个流入线框的基线 在单元格中,或单元格中的第一个流入表格行中的任何一个 先到了。如果没有这样的线框或表格行,则基线 是单元格内容边缘的底部。
这是理解行为的关键。这是非常技术性的,所以我会试着把它拆开。
第一个单元格有一个流入线框,由文本“cell1”组成。它的基线是文本的基线。
对于第二个单元格,所有非空白文本都将通过`float:left'从流中删除,并且所有空格都将被正常的空格规则删除。因此,它没有任何流入线盒。它也不包含任何流入表行,因此单元格的基线是单元格框内容边缘的底部。
由于表格单元格形成block formatting context,因此单元格的内容包含浮动,因此底部内容边缘是浮动的底部。
默认情况下,第一个单元格的垂直对齐值为baseline
。因此,它必须与第二个细胞的基线对齐,第二个细胞是浮体的底部。
现在,第一个单元格中的a
元素是未替换的内联元素。 Its height rules说
内联未更换框的垂直填充,边框和边距 从内容区域的顶部和底部开始,无关 与'线高'。但是,只有'线高'才被使用 计算线框的高度。
...第一个表格单元格的高度是其行框的堆叠高度,在这种情况下,它是它所包含的唯一行的行高。因此,a
元素填充和边框不会影响表格单元格的高度,实际上会转义第一个表格单元格,如果添加background-color
to the cells
正如已经指出的那样,决议是add vertical-align:middle
to the first cell。