为啥不垂直对齐:中间与表格单元格中的输入元素一起使用?

Posted

技术标签:

【中文标题】为啥不垂直对齐:中间与表格单元格中的输入元素一起使用?【英文标题】:Why doesn't vertical-align: middle work with input elements in a table-cell?为什么不垂直对齐:中间与表格单元格中的输入元素一起使用? 【发布时间】:2016-08-19 07:10:00 【问题描述】:

这是我的代码:

*                vertical-align: top; margin: 0; 
td               vertical-align: middle; border: 1px solid red; 
td:nth-child(1)  line-height: 3em; 
td:nth-child(2)  line-height: 4em; 
td:nth-child(3)  line-height: 0.1em; 
p, input         outline: 1px solid green; 
<table>
    <tr>
      <td>
        <p>
          Some vertically centered text.
        </p>
      </td>
      <td>
        <input type="text">
      </td>
      <td>
        <input type="text">
      </td>
    </tr>
</table>

可以看到,p 整齐地垂直居中,inputline-height: .1em 一样,而 inputline-height: 4em 被移到顶部。

经过长时间的研究,我没有找到这种行为的解释。

我设置了一个 jsfiddle:https://jsfiddle.net/dlenne/8xapwz11/14/。

【问题讨论】:

【参考方案1】:

您已经在td 上设置了vertical-align: middle,每个都是input 元素的父元素。

但是vertical-align 属性没有被继承 (source)。

因此,一种解决方案是将规则直接应用于输入:

*                vertical-align: top; margin: 0; 
td               vertical-align: middle; border: 1px solid red; 
td:nth-child(1)  line-height: 3em; 
td:nth-child(2)  line-height: 4em; 
td:nth-child(3)  line-height: .1em; 
p, input         outline: 1px solid green; 
input            vertical-align: middle;                /* new */
<table>
  <tr>
    <td>
      <p>Some vertically centered text.</p>
    </td>
    <td>
      <input type="text">
    </td>
    <td>
      <input type="text">
    </td>
  </tr>
</table>

另一种解决方案只是绕过line-height 规则,将输入的display 值从inline 切换到block

*                vertical-align: top; margin: 0; 
td               vertical-align: middle; border: 1px solid red; 
td:nth-child(1)  line-height: 3em; 
td:nth-child(2)  line-height: 4em; 
td:nth-child(3)  line-height: .1em; 
p, input         outline: 1px solid green; 
input            display: block;                /* new */
<table>
  <tr>
    <td>
      <p>Some vertically centered text.</p>
    </td>
    <td>
      <input type="text">
    </td>
    <td>
      <input type="text">
    </td>
  </tr>
</table>

参考资料:

Understanding vertical-align, or "How (Not) To Vertically Center Content" 10.8.1 Leading and half-leading(line-heightvertical-align 的 W3C 定义) Line-height inheritance

【讨论】:

首先我感谢大家非常有资格的回答!其次,我怀疑输入元素周围有一个虚拟或隐式对象,该对象应用了 line-height 属性,并且它的 vertical-align-property 设置为“top”。这基本上就是 Oriol 在下一篇文章中所写的,行框。另一个 CSS 的例子并不完全自我解释,但需要一个非常详细的隐式模型来理解它的规则...... 十亿次赞成...我在许多项目中多次使用vertical-align,它似乎总是给我带来问题,最后我在这里找到了这个答案一切都那么清楚“但是垂直对齐属性是不可继承的。”所以,在把我的下巴从地板上拿下来之后,我很高兴用td *vertical-align: whatever; 替换任何tdvertical-align: whatever; 实例,以获得我一直认为我与前一个相同的效果。非常感谢你做的这些!我期待着将来对这个属性的困惑会少得多。 @VoidKing,我很高兴能帮上忙。顺便说一句,这也有助于记住 vertical-align 仅适用于 table-cellinline-level 元素。 developer.mozilla.org/en-US/docs/Web/CSS/vertical-align【参考方案2】:

由于单元格有vertical-align: middle,其内容将对齐到单元格的中间。

但在这种情况下并不明显,因为内容垂直占据了所有单元格。

这是因为line-height 属性设置了line box 的最小高度,而您使用了一个非常高的值

td:nth-child(2) 
  line-height: 4em;

然后,输入是一个内联元素。所以它相对于该行框的垂直对齐将由输入的vertical-align 给出。

* 
  vertical-align: top;

如果你想在单元格的中间对齐输入,你应该在输入上使用vertical-align: middle将它对齐到它的行框的中间,也就是对齐到单元格的中间。

input 
  vertical-align: middle;

* 
  vertical-align: top;
  margin: 0;

td, input 
  vertical-align: middle;
  border: 1px solid red;

td:nth-child(1) 
  line-height: 3em;

td:nth-child(2) 
  line-height: 4em;

td:nth-child(3) 
  line-height: 0.1em;

p, input 
  outline: 1px solid green;
<table>
  <tr>
    <td>
      <p>
        Some vertically centered text.
      </p>
    </td>
    <td>
      <input type="text">
    </td>
    <td>
      <input type="text">
    </td>
  </tr>
</table>

【讨论】:

【参考方案3】:

我认为是因为这个:

*vertical-align: top;

当您使行高大于 td(parent) 时,它即 input(child) 会缩小并因此如下:vertical-align: top; 而不是 vertical-align: center;

【讨论】:

以上是关于为啥不垂直对齐:中间与表格单元格中的输入元素一起使用?的主要内容,如果未能解决你的问题,请参考以下文章

垂直对齐表格单元格中的文本[关闭]

如何垂直对齐表格单元格中的图像和文本?

vertical-align详解

使用 CSS Grid 和 Flexbox 水平对齐位于不同网格单元格中的元素

表格单元格中的垂直对齐以及浮动 div

垂直对齐中间与显示表格单元格不适用于图像