Winter evening

Centering an image

Back to September 2006

About this topic there are a lot of problems related especially to Internet Explorer's weird support of certain CSS properties. Basically, we want to center an image inside a container. An obvious problem could be the intrinsic dimension of the image. This is a problem related to dynamic websites. When we create a static webpage, we known in advance the dimensions of each element, because this is a necessary requirement of every well-designed page. Problems related to dynamic pages lie outside the scope of this writing, although they are really important in script-based websites (I'm really weak in PHP programming, so don't ask). However, I think it's possible to make scripts and CSS interact to gain an excellent control over layout (this is a basic feature of web languages).

The CSS code

body {
margin: 0;
padding: 0;
text-align: center;
}

.edicola {
margin: 5px auto;
padding: 0;
text-align: center;
border: 1px solid #999;
width: 150px;
height: 150px;
line-height: 150px;
display: block;
}


* html body .edicola img {
margin: 25px 0 25px 0;
}

img {
width: 133px;
height: 100px;
margin: 0 auto; 
padding: 0;
display:inline-block;
vertical-align: middle;
}

The theory behind

The code is slightly simple, but the underlying theory is not so trivial as it can look at first sight. The container (here selected with the class selector .edicola) has explicit dimensions, and its 'width', 'height' and 'line-height' properties have all the same value (150px). The 'line-height' property is very important in this case: in fact, «on a block-level, table-cell, table-caption or inline-block element whose content is composed of inline-level elements, 'line-height' specifies the minimal height of line boxes within the element». Combined with the 'height' property (values must be equal), it centers an element vertically within a container. Note that the container has also the declaration 'text-align: center', required by Internet Explorer to center an element horizontally.

Next step, the image. The image dimensions differ from each other, so we get a rectangle and not a square. It has the declaration 'display: inline-block' together with 'vertical-align: middle'. The inline-block value «causes an element to generate a block box, which itself is flowed as a single inline box, similar to a replaced element. The inside of an inline-block is formatted as a block box, and the element itself is formatted as an inline replaced element». Then we use the 'vertical-align' property, which «affects the vertical positioning inside a line box of the boxes generated by an inline-level element». We give this property the value of middle, which is specified to «align the vertical midpoint of the box with the baseline of the parent box plus half the x-height of the parent». That's all, but not for Internet Explorer.

In fact, this browser requires an hack (marked in red) to display the image vertically aligned. The top and bottom margin values are given by the following calculations:

150px - 100px = 50px
50px : 2 = 25px

'150px' is the minimal height of the container and '100px' is the height of the image. Then we divide the resulting number in two and we get our top and bottom margin values. Note that the image has also the left and right margin set to 'auto', to center it horizontally in compliant browsers. The hack mentioned above can also be given through conditional comments.