Vertical align block level element inside a block level element

Salman A picture Salman A · Apr 6, 2009 · Viewed 14.6k times · Source

I need to center align images (variable width and height) inside block level elements of fixed width and height. The css markup looks something like this:

<div style="float: left; width: 100px; height: 100px;"><img src="yada" width="50" height="60"></div>
<div style="float: left; width: 100px; height: 100px;"><img src="yada" width="60" height="50"></div>
<div style="float: left; width: 100px; height: 100px;"><img src="yada" width="75" height="75"></div>

The point is, that the images align themselves to the top right corners of the container div. I want them to be centered, both horizontally and vertically. I have tried setting the img tag style as follows:

img {
display: block;
margin: auto;
}

This center-aligns the img horizontally but not vertically. I need both so that the gallery page looks neatly aligned. I need to avoid using tables at all cost although this produces the result exactly as I need. I need a portable, hack-less CSS solution.

Answer

bobince picture bobince · Apr 6, 2009

Yes, vertical margins are calculated in a fundamentally different way to horizontal ones; ‘auto’ doesn't mean centering.

Setting ‘vertical-align: middle’ on the image elements sort of works, but it only aligns them relative to the line box they're currently on. To make the line box the same height as the float, set ‘line-height’ on the container:

<style>
    div { float: left; width: 100px; height: 100px; line-height: 100px; }
    div img { vertical-align: middle; }
</style>

You have to be in Standards Mode for this to work, because otherwise browsers render images-on-their-own as blocks instead of inline replaced elements in a text line box.

Unfortunately, IE (up to 7 at least) still keeps the block behaviour even in its attempt at a Standards Mode. There is a technical reason for this, namely that IE is pants.

To persuade IE that you really mean it about the images being part of a text line, you have to add some text inside the div — even a normal space will do it, but you could also try a zero-width-space:

<div><img src="http://i.stackoverflow.com/Content/Img/stackoverflow-logo-250.png" width="50" height="60" />&#8203;</div>
<div><img src="http://i.stackoverflow.com/Content/Img/stackoverflow-logo-250.png" width="60" height="50" />&#8203;</div>
<div><img src="http://i.stackoverflow.com/Content/Img/stackoverflow-logo-250.png" width="75" height="75" />&#8203;</div>