The PNG Guide is an eBook based on Greg Roelofs' book, originally published by O'Reilly.



Client-Side Workarounds: The OBJECT Tag

Suppose that we would like to use PNGs wherever possible but still allow older browsers to see JPEGs or GIFs. Is there a way to do this? The answer is either ``sort of'' or ``yes,'' depending on the approach one takes. In Chapter 1, "An Introduction to PNG", I mentioned a client-side approach involving the HTML 4.0 OBJECT tag, but I also noted that neither of the Big Two yet handles such things correctly, and earlier in this chapter I enumerated some of the specific problems in the two browsers. The other approach is a server-side method involving content negotiation. We'll come back to that one later.

First, let us take a closer look at the client-side method. HTML 4.0's OBJECT tag was designed to be a generalized replacement for the HTML 3.2 IMG and APPLET tags and for Netscape's EMBED tag. Since OBJECT is a container, it can contain other elements inside it, including nested OBJECTs. The rules for rendering them are simple: start with the outermost OBJECT; if you can render that, do so, and ignore what's inside. Otherwise, continue peeling back the outer layers until you find something that can be rendered.

In the case of images, the following two elements are equivalent:

<IMG SRC="foo.png"
 ALT="[This text is visible if the image is not rendered.]">
<OBJECT TYPE="image/png" DATA="foo.png">
   [This text is visible if the image is not rendered.]
</OBJECT>

Because OBJECTs can be used for many things, the image/png MIME type in this example is strongly recommended so that the browser can unambiguously identify the data as an image (rather than, say, a Java applet) and, if it knows it has no support for the type, avoid contacting the server unnecessarily. For JPEGs or GIFs, the MIME type would be image/jpeg or image/gif, respectively. Both IMG and OBJECT tags may include optional HEIGHT and WIDTH attributes, but as we noted earlier, Netscape requires them in order to invoke an image-handling plug-in for an OBJECT tag.[16]

[16] If Netscape ever modifies their plug-in code to work with IMG tags, presumably the HEIGHT and WIDTH attributes will be required there, as well. Fortunately, this is not a very onerous requirement for content producers.

The trick that should allow both OBJECT-recognizing browsers and pre-OBJECT browsers to render something sensible is to wrap a GIF or JPEG version of an image, referenced via an old-style IMG tag, inside a new-style OBJECT tag that references a PNG version of the same image. In other words, one does something like the following:

<OBJECT WIDTH="160" HEIGHT="160" DATA="foo.png" TYPE="image/png">
   <IMG WIDTH="160" HEIGHT="160"  SRC="foo.jpg"
    ALT="[rare photo of the incredible foo]">
</OBJECT>

If we decide to accommodate only browsers that support either OBJECT or PNG (or both) but don't care about older browsers that support neither, we can get a little fancier with nested OBJECTs:

<OBJECT WIDTH="160" HEIGHT="160" DATA="foo.png" TYPE="image/png">
<OBJECT WIDTH="160" HEIGHT="160" DATA="foo.jpg" TYPE="image/jpeg">
   <IMG WIDTH="160" HEIGHT="160"  SRC="foo.png"
    ALT="[rare photo of the incredible foo]">
</OBJECT>
</OBJECT>

A browser that implements both PNG and HTML 4.0 will render the outer OBJECT PNG; one that implements HTML 4.0 but not PNG will render the inner OBJECT JPEG; and one that implements PNG but not HTML 4.0 will render the innermost IMG PNG. (And, of course, a browser with no image support will render the text in the IMG tag's ALT attribute.)

The reason these tricks don't work in practice is that some browsers--particularly Netscape Navigator and Microsoft Internet Explorer, but undoubtedly others as well--added incomplete or incorrect support for OBJECT before the HTML 4.0 specification was formally approved in December 1997. As I've already noted, no released version of either of the Big Two browsers would invoke its native image-handling code when it encountered an OBJECT image, even as late as February 1999. Navigator always renders the inner IMG unless a plug-in is available; MSIE either pops up an error box claiming to need an ActiveX control or, in our tests, manages to crash while invoking a Netscape PNG plug-in installed elsewhere on the system. (I've also noted that Internet Explorer attempts to render all OBJECTs in a nested set, not just the outermost one.) Older versions of both browsers, and, likewise, all versions of Opera to date, behave as expected and simply ignore OBJECT images.




Last Update: 2010-Nov-26