在table-cell元素中使用float属性会将先前的内容向下滑动

时间:2015-12-19 18:26:51

标签: html css css-float vertical-alignment

我试图在具有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;
&#13;
&#13;

3 个答案:

答案 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;
}

http://jsfiddle.net/vg5j7xgc/5/

答案 2 :(得分:1)

CSS 2.1 says

  

单元格的基线是第一个流入线框的基线   在单元格中,或单元格中的第一个流入表格行中的任何一个   先到了。如果没有这样的线框或表格行,则基线   是单元格内容边缘的底部。

这是理解行为的关键。这是非常技术性的,所以我会试着把它拆开。

第一个单元格有一个流入线框,由文本“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