Centering Images in a Box via CSS

It’s a testament to how badly thought out web standards are that various simple, common tasks, such as displaying an image centered in a box, are rocket science. (More examples: we still don’t have a decent mechanisms for handling headers and footers, text columns, footnotes, or non-scrolling UI elements.)

When I google for a solution, the top linked page addressing it appears to be here. I got a bit leery of the proposed solution when I realized it involved (a) IE-specific conditional hacks with comment jutsu, and (b) the insertion of empty spans. I became even more leery when I discovered I’d need to rework it to handle images wrapped in anchor tags.

There is one mechanism in CSS for centering images in boxes that Just Works. Unfortunately it involves setting them to be background-images (in other words, rather than being able to apply properties to an img tag to make it behave as desired, you need to replace it with some other element and then give it a background-image property — this is typical of the way CSS “solves” common problems).

Fortunately, this works for the problem I have at hand, and I can add the “linking” functionality back in either by wrapping my anchor tags around a transparent gif scaled to fill the relevant box or attaching an event handler to the box (a span). (Edit: note that my final solution is more elegant and doesn’t do any such nonsense.)

This leaves me with per-item html that looks like this:

<span class="grid_item" style="background-image: url(example.jpg)">
  &nbsp;
</span>

vs.

<div class="wraptocenter">
  <span></span>
  <img src="example.jpg">
</div>

But the win is that my CSS is shorter, simpler, and doesn’t involve unused tags and IE wankery (although it occurs to me that the linked solution might work better if they simply used spans instead of divs as the containers, since — like me — they’re completely overriding the display behavior of the element anyway, so why not take advantage of the fact that inline-block works for span (I believe) in IE 6/7?)

Now because I’m using a background-image I can’t take advantage of proportional scaling using min- and max- dimensions (so I can’t usefully display an image inside a box scaled to fit in that box). This is one of those cases where CSS is simply infuriating.

Anyway, here’s my CSS (the grid_item is intended to sit inside a larger div and act like a table cell):

span.grid_item {
  display: inline-block; /* should work for spans in IE 6/7 */
  width: 128px;
  height: 128px;
  background-position: center; /* why can't all centering be this easy? */
  background-repeat: no-repeat;
}

I haven’t actually tested this under an old IE yet, I’m relying on quirksmode, so take everything I say with a grain of salt and use with caution.

Post Script

I’ve put up my test page here, and tested it with Internet Explorer 7 and it works perfectly. (Thank you, again, quirksmode.) I think you’ll agree this is a much more elegant solution (perhaps not compatible with IE 5.x on a Mac but — seriously — who cares?). What’s more, I’ve made it even cleaner after realizing that anchor tags are inline by default and hence I don’t even need to use a span tag or jQuery kung fu to implement link behavior. (So if the HTML were generated server-side and the browser had no CSS support everything would behave correctly.)