Vertical align all(!) elements in TD?

前端 未结 11 1054
鱼传尺愫
鱼传尺愫 2021-01-31 14:28

I have a simple table with 1 TD with vertical-align:middle;. This TD contains an Image :



        
11条回答
  •  醉梦人生
    2021-01-31 14:56

    In all the cases, the vertical-align: middle; on the td does what is expected of it. That is, align the td to the center of that row and the entire contents of the td to the vertical middle (by default) leaving equal spaces at the top and the bottom.

    Here is what the W3 Spec says about vertical-align: middle:

    The center of the cell is aligned with the center of the rows it spans.

    enter image description here

    Row height calculation:

    The height of a 'table-row' element's box is calculated once the user agent has all the cells in the row available: it is the maximum of the row's computed 'height', the computed 'height' of each cell in the row, and the minimum height (MIN) required by the cells.

    In CSS 2.1, the height of a cell box is the minimum height required by the content. The table cell's 'height' property can influence the height of the row (see above), but it does not increase the height of the cell box.

    Cell boxes that are smaller than the height of the row receive extra top or bottom padding.

    As a result of the above, the height of the tr and the td becomes 100px but the cell box takes up only the amount of height required by the contents (img height = 43px). Now since the Cell box is smaller than the row height, extra padding is added like shown in Box 5 of the image above and thus makes the contents also get aligned to the middle.


    TD has only image:

    When there is only an img, the content height is equal to the height of the img. So it gets positioned to the middle.

    enter image description here

    As can be seen in the above image, this does not require a vertical-align: middle on the img explicitly because the td aligns its contents to the middle.


    TD has only inline data:

    When the td has only a span or span plus an inline div, the height of the content is equal to the default line-height for text (or any specified line-height). In this case also, the td aligns it correctly.

    enter image description here

    When the text content goes beyond the first line (refer to the demo), you can see that the td automatically pushes the first-line (marked in cyan background) upwards to ensure that the contents on the whole is aligned to the middle (not just a single line).


    TD has an image and a span:

    When we put an img and a span (inline text) within the td, the content height becomes equal to the height of the img plus the line-height of the second and subsequent lines.

    In this situation, there are two possible cases as described below:

    Case 1 - img tag has no vertical-align specified

    In this case, the img is aligned to the baseline (default). Then the td aligns the entire content to the middle. This means the td leaves around 28.5px (= (100-43)/2) gap at the top and the bottom of the content. Again, the vertical-align on td does the job, it puts the contents in the middle (that is, leave equal gap on top and bottom). But the text gets pushed down because img height is more.

    enter image description here

    If we reduce the img height to less than the line height (say 10px), we can see that even with img + span it gets aligned to the middle.


    Case 2 - img tag has vertical-align: middle

    In this case also vertical-align on the td does the same as what it did for Case 1. However, the text in this case is near the middle because the img is also aligned to the middle of the line.

    enter image description here

    table {
      border: solid 1px red;
    }
    td {
      height: 100px;
      width: 200px;
      vertical-align: middle;
      border: solid 1px green;
    }
    img {
      height: 43px;
      width: 43px;
      border: solid 1px green;
    }
    .one td + td img {
      vertical-align: middle;
    }
    .three td + td img {
      height: 10px;
      width: 10px;
    }
    .four img {
      vertical-align: middle;
    }
    .five img + img{
      height: 50px;
      width: 50px;
    }
    td:first-line {
      background-color: cyan;
    }
    div {
      display: inline;
    }
    aaa
    aaa
    aaa
    aaa aaaaaaa aaaaaaaa aaaaaaaa
    Case 1 Image + Span Case 1 Image + Span
    Case 2 Image + Span Image + Span + more text.......
    Case 3 Image + Span text... Image + Span + more text.......

提交回复
热议问题