Search code examples
htmlcssvertical-alignment

Vertical align all(!) elements in TD?


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

table
{
  border:solid 1px red;
  width:300px;
}

td
{
  height:100px;
  vertical-align:middle;
  width:100%;
  border:solid 1px green;
}
img
{
  height:43px;width:43px;
}

span
{
  vertical-align:middle;
}
<!DOCTYPE html>
<html>
  <head>
    <meta charset=utf-8/>
    <title>JS Bin</title>
  </head>
  <body>
    <table>
      <tr>
        <td>
          <img src='http://static.jsbin.com/images/favicon.png'/>
        </td>
      </tr>
    </table>
  </body>
</html>

Everything is Ok and the IMG is vertical-aligned.

But If I add another elements after that Image ( a span for example ) :

table
{
  border:solid 1px red;
  width:300px;
}

td
{
  height:100px;
  vertical-align:middle;
  width:100%;
  border:solid 1px green;
}
img
{
  height:43px;width:43px;
}

span
{
  vertical-align:middle;
}
<!DOCTYPE html>
<html>
  <head>
    <meta charset=utf-8/>
    <title>JS Bin</title>
  </head>
  <body>
    <table>
      <tr>
        <td>
          <img src='http://static.jsbin.com/images/favicon.png'/>
          <span>aaa</span>
        </td>
      </tr>
    </table>
  </body>
</html>

Question

Doesn't the vertical align of the TD should vertical align all its childs ?

How can I make the span to be centered as well ?

NB

I don't want to add another TD , nor using float with padding/margin. IE8+.

edit:

Desired result :

enter image description here


Solution

  • Question
    Doesn't the vertical align of the TD should vertical align all its childs ?

    NO.
    When you apply vertical-align to td, it is only applied to td, and is not inherited by any of its children.

    If i have a TD with only span in it - it will vertical align. If I had a TD with only IMG inside it - it will also align.

    This is because of the way vertical-align for td works. The total height of the cell i.e td is calculated and the whole cell is aligned vertically.

    If there is a single img, then the height of td is same as that of img, so it seems that vertical-align for img is also middle. But actually, the td is vertically aligned to the middle with the img as vertical-align : baseline

    Same is the case when there is a single span.

    but if i have both - it doesn't. why is that ?

    Because now, the height of td is the combined height of both img + span. So, actually, td is vertically aligned in the middle, but not img and span.

    How can I make the span to be centered as well ?

    You need to apply this CSS :

    td > * {
        vertical-align : middle;
    }
    

    This will apply the CSS to all the children.

    Check the JSFiddle for a better picture.

    Hope, this answers your question.