I have a simple table
with 1 TD
with vertical-align:middle;
. This TD
contains an Image
:
DEMO
just add this class:
td *{
vertical-align:middle
}
question is why when you add a pic to the td
text goes bottom of pic and not any more middle of td.
this is my answer:
when you set td
vertical-align
to middle
it should not set all content vertical-align
to middle
, they are still baseline
. and when you add a pic to the text, the line height rise to the height of image and text is bottom of this height, so you need to set vertical-align
to middle
for fix this problem.
here you can see what i said: DEMO
and sorry about my bad english
<style>
table
{
border:solid 1px red;
width:300px;
}
td
{
height:100px;
width:100%;
border:solid 1px green;
vertical-align:middle;
line-height:100px;
}
img
{
height:43px;width:43px;
vertical-align:middle;
}
</style>
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.
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.
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.
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.
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.
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;
}
<table>
<tr class='one'>
<td>
<img src='http://static.jsbin.com/images/favicon.png' />
</td>
<td>
<img src='http://static.jsbin.com/images/favicon.png' />
</td>
</tr>
<tr class='two'>
<td>
<div>aaa</div>
<span>aaa</span>
</td>
<td>
<div>aaa</div>
<span>aaa aaaaaaa aaaaaaaa aaaaaaaa</span>
</td>
</tr>
<tr class='three'>
<td>
Case 1
<img src='http://static.jsbin.com/images/favicon.png' />
<span>Image + Span</span>
</td>
<td>
Case 1
<img src='http://static.jsbin.com/images/favicon.png' />
<span>Image + Span</span>
</td>
</tr>
<tr class='four'>
<td>
Case 2
<img src='http://static.jsbin.com/images/favicon.png' />
<span>Image + Span</span>
</td>
<td>
<img src='http://static.jsbin.com/images/favicon.png' />
<span>Image + Span + more text.......</span>
</td>
</tr>
<tr class='five'>
<td>
Case 3
<img src='http://static.jsbin.com/images/favicon.png' />
<img src='http://static.jsbin.com/images/favicon.png' />
<span>Image + Span text...</span>
</td>
<td>
<img src='http://static.jsbin.com/images/favicon.png' />
<span>Image + Span + more text.......</span>
</td>
</tr>
</table>
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.
This CSS attribute doesn't go on any other kinds of elements. When the novice developer applies vertical-align to normal block elements (like a standard ) most browsers set the value to inherit to all inline children of that element.
You simply need to add vertical-align: middle
to the <img>
class.
Your CSS should look like this...
table
{
border:solid 1px red;
width:300px;
}
td
{
height:100px;
vertical-align:middle;
width:100%;
border:solid 1px green;
}
img
{
height:43px;width:43px;
vertical-align: middle;
}
You can view the Sample Fiddle...