简体   繁体   中英

Why doesn't vertical-align: middle work with input elements in a table-cell?

Here is my code:

 * { 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> 

As one can see, the p is neatly vertically centered, as well as the input with line-height: .1em , while the input with line-height: 4em is moved to the top.

I did not find an explanation for this behaviour after lengthy research.

I set up a jsfiddle: https://jsfiddle.net/dlenne/8xapwz11/14/ .

You've set vertical-align: middle on the td , each of which is a parent of an input element.

But the vertical-align property is not inherited ( source ).

So, one solution is to apply the rule directly to the inputs:

 * { 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> 

An alternative solution simply bypasses the line-height rules by switching the display value of the inputs from inline to 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> 

References:

Since the cell has vertical-align: middle , its contents will be aligned to the middle of the cell.

But in this case it's not noticeable, because the contents occupy all the cell vertically.

That's because the line-height property sets the minimum height of a line box , and you use a very tall value

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

Then, the input is an inline-level element. So its vertical alignment with respect to that line box will be given by the vertical-align of the input.

* {
  vertical-align: top;
}

If you want to align the input at the middle of the cell, you should use vertical-align: middle on the input to align it to the middle of its line box, which is aligned to the middle of the cell.

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> 

I think its because of this :

*{vertical-align: top;}

When you make the line height bigger than the td (parent) it ie input (child) scales out and hence follows: vertical-align: top; rather than vertical-align: center;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM