AaronCrane.co.uk

Unbreaking <img align> in Opera

Opera has what seems to be a peculiar bug in its treatment of HTML <img> elements that have align attributes. Fortunately, it’s relatively easy to work around.

There are two surprising aspects to the way Opera handles <img align>. First, it appears to put a small amount (2 pixels) of left and right margin on aligned images. Second, and much more surprisingly, wide text and other images inside the element containing the aligned image don’t leave room for it.

This seems enormously surprising. This test page demonstrates the issue. It uses markup like this:

<div class=demo>
  <div>
    <img src="blue.png" width=50 height=50 alt="" align=right>
    <img src="red.png" width=75 height=75 alt="">
  </div>
</div>

with these CSS rules:

.demo div {
  background: #c9c;        /* lilac background to show box size */
  width: 100px;            /* restrict width of box */
}

.demo img {
  vertical-align: bottom;  /* avoid surprising descender space */
}

I expect this to be rendered as a 100×125-pixel lilac box, containing blue.png at the top-right corner, and red.png at the bottom-left corner. Opera 9.51 (the current version at this writing) instead renders it as a 100×75-pixel lilac box, containing blue.png near the top-right corner, and red.png at the top-left corner, occluding part of blue.png.

This doesn’t seem to be a recent change in Opera; I’ve tried one or two older versions and they behave the same way. My suspicion is that this is some kind of quirk for compatibility with Internet Explorer, but it happens even when rendering in Standards or Almost Standards mode (where document.compatMode contains the value CSS1Compat).

I’m aware that the align attribute on <img> is considered deprecated in HTML 4, and that it’s absent from the current drafts of HTML 5 on the grounds that such presentational attributes are better handled by CSS. However, there are still plenty of HTML documents in the world which use <img align>, some of which I have to deal with in a professional capacity. It strikes me as odd that Opera chooses to implement this presentational HTML feature in a way that neither matches its own CSS float behaviour nor obeys the text-flow requirement described by the HTML 4 specification.

The workaround requires only setting explicit CSS rules to override Opera’s peculiar default. First, explicitly set the left and right margin to a zero length on images that have an align attribute, whatever the value of that attribute:

img[align] {
  margin-left: 0;
  margin-right: 0;
}

Secondly, force Opera to use its perfectly good CSS float behaviour for aligned images:

img[align="left"]  { float: left }
img[align="right"] { float: right }

Since these additional rules just force rendering to happen in the obvious way, it shouldn’t be problematic for non-Opera browsers to see them. (Though versions of Internet Explorer before version 7 won’t obey them, because they don’t handle attribute-value selectors.) However, if you have some mechanism for handling per-browser stylesheets, you may choose not to show these rules to non-Opera browsers.