Saturday, April 19, 2008

Vertical-alignment without tables

One of the common problems I come across when creating a picture gallery, is to vertically align images.

Say, I have 4 images, with variable height and width, but fixed max-height and max-width and a title underneath.

I could use

<div style="float:left; margin-right:10px;">
  <div class="outerbox" style="width:100px; height:100px; border:1px solid #999;">
  <img="src=path" class="innerbox"/>
  </div>
  <div>Title</div>
</div>

I will get an image gallery which looks like this:

image

Here, if I want to center the images inside the grey box, I just need to add the declaration, text-align:middle, to the container, however, if I want to vertically align these, I have nothing that I can use, short of using tables with a valign attribute. This is because the 'vertical-align' style declaration does not mimic 'valign' in all cases. A detailed analysis of vertical-align by Gary Kistner can be found here.

Initally, I was delighted to see that upon giving the div tag a display property of 'table-cell' it uses it implements like a valign tag. [click to enlarge]

image

But unfortunately, IE6 does not support this. For a detailed description on how browsers implement the display property, visit this page on quirksmode.

The previous article by Gavin Kistner offers two workarounds.

Method one works in the following way (I call it the Duck and Head-up method): assuming a fixed height for the inner content (im my example the img with class innerbox), position it absolutely inside the container (outerbox) with the top-edge at 50% of the outerbox height. Now move back the innerbox up by half its own height, by using margin-top:-y, (y=half of inner box height).

I haven't tried this, simply because in my case, the inner content does not have a fixed height.

The second may perhaps work because it assumes a single line of text inside the box (which a single inline image should be) and a fixed height for the outerbox, (which is true in my case), and then setting the line-height for the parent (outerbox) to the fixed-height. Let's see how that works. Sadly, it only works in the case of text. probably because it relates to font-size and not image-height [In the following example, text-height + above and below height = 140 which was the specified line-height]

image 
[In the above example, height declaration replaced by line-height declaration]

I came up with a workaround which included some additional mark-up. Add a non-breaking space (&nbsp;) before the image, set the font-size to 1px and increase the outer-box width a little;  that way the image is seen as a part of the running text and Mozilla and Safari render this correctly [look at the second box]. But as always IE6 refuses to implement it this way! Sigh.

image

Finally, this site seems to have find a solution using a font-height declaration for IE6 and then hiding it from other browsers. CSS vertical-align.

But clearly if you want an excess mark-up and hack free solution, tables are probably your only resort - at least for an image gallery.