
The Vanishing Image: XHTML 2 Migration Issues
by Mark PilgrimJuly 02, 2003
Mapping a Migration Path
Why bother talking about a migration path at all? All the work I have seen so far in the XHTML 2.0 world has been about what it would be like to be there. Which makes sense, since it's not finished yet and the HTML Working Group is still hashing out the details. However, there has been a distressing lack of information about what it will take to get there from where we are now. Even assuming that where we are now is "valid XHTML 1, used properly" (a huge assumption for most sites), there is still no information about how to make the leap from there to XHTML 2.
Members of the HTML Working Group seem totally unconcerned with this. They have indicated publicly (on the www-html mailing list) that they see no need for a migration path from XHTML 1 to XHTML 2. XHTML 2 is not a replacement for XHTML 1, they say. XHTML 2 is only for new documents and applications built from scratch; no one will bother converting existing documents and applications.
However, experience has shown us that there is a natural demand for the latest and greatest, if only out of fear. Developers see "XHTML 2" and mistakenly assume that it is a replacement for "XHTML 1". And they fear that if they only know "XHTML 1", HR departments will soon start rejecting their resumes because they are filtering on "XHTML 2" (which probably is true; I mean, let's face it). Meanwhile, the HTML Working Group has done just about everything it can do to create confusion in the marketplace by giving XHTML 2 the same name as the language it's not replacing, the same MIME type, and the next major version number.
Looking even further ahead, it is important to note that XHTML 2 is the only W3C-approved markup language that is evolving. The HTML Working Group has stated publicly that there will be no XHTML 1.2. Nor will there be an HTML 5 or even an HTML 4.1. The future will be filled with web features that require XHTML 2. (The first of those, XForms, will be the subject of a future article.)
All of which brings us, in a roundabout sort of way, to today's topic:
The <object> Element
Although it's been around for years, the <object>
element is unappreciated and rarely used. It was meant to be an
replacement for several other elements: <img>,
<applet>, and the non-standard
<embed>. <object> features
multilevel fallbacks; you are supposed to be able to define multiple
choices for a single object (for example, the same image in multiple
formats), and browsers are supposed to render the first one they can. If
none of the choices work out, you can fall back on text; not just plain
text (like the alt attribute of an <img>),
but full HTML markup.
This will be clearer with an example. Here is an
image, which you could embed in a page with a single
<img> element:
<img id="beagle"
src="beagle.jpg"
alt="Beagle in a woman's lap"
width="152"
height="160" />
You could embed the same image using the <object>
element, like this:
<object id="beagle"
type="image/jpeg"
data="beagle.jpg"
width="152"
height="160">
<p><span class="breed">Beagle</span> in a woman's lap</p>
</object>
Several things to note here:
- The
<img>element does not specify a MIME type; that is handled by the web server. The<object>element explicitly states the MIME type of the linked image file. - The
altattribute of the<img>element is limited to plain text. The<object>element achieves the same purpose (a graphic with text fallback), but it can support full HTML markup for the text fallback. - The
<object>version won't actually work.
Why won't it work? Well, it will work in some browsers. But not in
Internet Explorer. The <object> element is a good
idea; unfortunately, it came a bit too late in the game. Before
<object> was officially added to the HTML specification
in 1997, Microsoft had already introduced its own vendor-specific element
in Internet Explorer 3.0 as a way of embedding ActiveX controls in web
pages: an element named... <object>.
When <object> was later standardized, Microsoft
retrofitted support for it, sort of. Except that, to this day, even the
latest version of Internet Explorer treats all <object>
elements as ActiveX controls. Which means that if you have your security
settings on "high" (disabling all ActiveX controls), you won't see any
<object> elements, even ones that have nothing to do
with ActiveX (like the above example).
Even if ActiveX in enabled (which it is by default), Internet Explorer renders the above image with a nasty border, and two sets of scroll bars. (demo)
Oh, and remember when I said that you were supposed to be able to nest
<object> elements and let the browser choose between
multiple formats of the same image? Well, that doesn't work in Internet
Explorer either; instead of rendering the first one it understands, it
renders all of them.
And this is why you've never heard of the <object>
element.
But no big deal, right? I mean, who cares about
<object> since we'll always have
<img>?
Bye, Bye img
XHTML 2 doesn't have an <img> element. It doesn't
have an <applet> element either. Both have been
obsoleted by -- wait for it... -- <object>!
So is there a way to ease the migration to XHTML 2? Is there a way to
start using <object> now instead of
<img>?
A Partial Solution
Let's be clear: the problem is Internet Explorer. Mozilla (and Mozilla
derivatives like Netscape )7 renders <object> just
fine. So does Opera. (Here's that demo
again of the picture of the beagle. Here are some
more tests to check your browser's support for
<object>.) Internet Explorer has four problems:
- Renders all nested
<object>elements. - Renders visible border by default.
- Renders visible scrollbars by default.
- Doesn't render if ActiveX is disabled.
The first problem can be worked around by simply not nesting
<object> elements. ("Doctor, it hurts when I do
this...") But that's a cop out. What if you really want to use fallbacks
for different image formats? Then you can use what are called conditional
comments, a Microsoft-specific technology that doesn't conflict with any
standards and doesn't cause any compatibility problems in other browsers.
(
more on MSDN)
Let's say you had two versions of the beagle picture, a JPG and a TIFF. It looks like this:
<object
type="image/tiff"
data="beagle.tiff"
width="152"
height="160">
<object
type="image/jpeg"
data="beagle.jpg"
width="152"
height="160">
</object>
</object>
But in Internet Explorer, this will render both the TIFF and the JPG (that's wrong!), unless we use conditional comments:
<object
type="image/tiff"
data="beagle.tiff"
width="152"
height="160">
<!--[if !IE]>
<object
type="image/jpeg"
data="beagle.jpg"
width="152"
height="160">
</object>
<![endif]-->
</object>
The second problem, the visible border, can be solved with a clever bit of Javascript. (All of the following Javascript solutions were donated by a semi-anonymous reader named "John" when I posed this question on my own personal site several months ago. Thanks, John.)
The trick to tackling the <object> element is to
realize that it acts like an <iframe>; that is, it is
its own canvas within a canvas. Within the DOM, an
<object> has its own body with all its own
properties. So to remove the border, we simply do this in our
window.onload function (demo):
beagle.body.style.border = 'none';
(beagle is the value of the id attribute we
defined in our <object> element.)
The third problem, the visible scrollbars, can be solved in a similar fashion (demo):
beagle.body.style.margin = '0';
beagle.body.style.padding = '0';
beagle.body.style.overflow = 'hidden';
You're likely to have more than one <object> per
page. Even if you're not in a dynamic application environment, you'll
want to abstract this Javascript code into a single function that you can
just link from each page, without worrying about the specific objects or
IDs on each page. You can do that with the
getElementsByTagName function (demo):
<script type="text/javascript">
function fixObjectImages ()
{
var objs = document.getElementsByTagName ('OBJECT');
for (n = 0; n < objs.length; n++)
{
var obj = objs [n];
if ((obj != null && obj.type != null)
&& ((obj.type == "image/jpeg") || (obj.type == "image/gif")))
{
fixObject (obj);
}
}
}
function fixObject (obj)
{
obj.body.style.border = 'none';
obj.body.style.margin = '0';
obj.body.style.padding = '0';
obj.body.style.overflow = 'hidden';
}
window.onload = fixObjectImages;
Unfortunately, the fourth problem can't be worked around. Internet
Explorer incorrectly treats all <object> elements as
ActiveX controls and, therefore, won't render them if ActiveX is disabled.
Depending on the user's security settings, the image may simply not
appear; worse, they may be prompted with a "Would you like to allow
programs such as ActiveX controls to Run?" dialog, which is likely to
scare off even the most dedicated readers.
Postscript
Remember when I said that Internet Explorer was the only browser with
<object> issues? I lied. There are other issues, of
varying degrees of importance.
|
More Dive Into XML Columns | |
- Mozilla 1.3 doesn't handle the
<object>image the same way as an<img>image. Right-clicking on it will not show you the usual image properties, or "block images from this server", or any other image-specific functions. I believe this will be fixed in Mozilla 1.4. Opera 7 has a similar problem. - Opera 7 treats
<object>like inline frames (the<iframe>element). This means that if the user has intentionally disabled<iframe>support (say, to block ads, a common use of iframes), they won't see your<object>either. - Several browsers, including Opera 7 and the latest final candidate
release of Mozilla 1.4, will not display the fallback text within an
<object>if images are disabled. - On the flip side, if the user has disabled images in Internet Explorer, it will still render your image-in-an-object.
- Screen readers for the blind, such as JAWS, will read the text of an
image's
altattribute aloud. However, they do not support reading the fallback text within an<object>element, thus rendering your objects completely inaccessible. - I've also seen unconfirmed reports that Internet Explorer doesn't let
you position anything over an
<object>. For example, on an interactive site, you could create a draggable<div>on top of an<img>element, but that doesn't work with<object>.
Bottom line: using <object> as a replacement for
<img> is not a safe bet right now. It's possible that
by the time XHTML 2 is finalized, and we have working implementations in
next-generation browsers, the current generation of browsers will have
fixed these quirks. But from here the migration path to XHTML 2 looks a
little bumpy.
Are you planning to migrate to XHTML 2? Share your views in our forum.
(* You must be a member of XML.com to use this feature.)
Comment on this Article
| Titles Only | Titles Only | Newest First |
- Wait A Minute
2006-07-24 18:19:08 jonvs [Reply]
The point of your article is about the <object> tag, but you didn't mention that in XHTML 2.0 you can say the following instead of using either <img> or <object>, which in my opinion is much easier:
This is what will show up if the image cannot be displayed.
The W3C did this to change "alt" to its intended purpose ... to offer descriptions of the image.
- Wait A Minute
2006-07-24 18:49:03 jonvs [Reply]
Sorry, I didn't know that would be parsed.
<p src="image.jpg"> This is what would display if the picture cannot be displayed.</p>
- Wait A Minute
- Minor comments.
2003-07-16 12:20:16 baafie sjakie [Reply]
You (the author of this article) have a valid point when you say people will want to upgrade to XHTML 2, against the HTML Working Group's expectation/intention. From the tone of this article, one would assume you find this a bad development; I however disagree: I think people should update their website to comply with the latest standards. Authors will have to rewrite their pages into XHTML 2.0, but, with server-side scripting and CSS in mind, this should be a not so very difficult task.
You are right when you say IE is not XHTML 2 compatible, which is yet another reason not to use IE, and yet another reason to tell other people not to use IE.
On a different note, I think your tests of XHTML 2.0 compatibility are rather useless. XHTML 2.0 is not even out of public draft yet. Aiming to be the first to analyse new developments is generally a good attitude, but I don't think you should bother checking mainstream browser compliance of those that do not officially support the implementation of a standard which is yet to be finalized. After all, you were writing an article about XHTML 2 and not about the poor implementation the OBJECT HTML (not XHTML) object in IE, right?
- Minor comments.
2007-01-07 12:52:55 kamahl [Reply]
Well, i completely agree with this but there is a problem: users. Many windows users will always have IE 'cause they are afraid installing new software or they even can't do it. Or they are contented with their browser and nothing better don't exists for them. (From their point of view.) Also a common user has no idea about how internet works and if you'll try to explain him what is xhtml or <object> you'll probably not succeed. Unfortunately, I know a lot of such people.
According to IE problems & bugs I use xml rather than xhtml/html.
- Minor comments.
- The fifth problem
2003-07-06 09:41:20 John Lloyd-Jones [Reply]
Alas, there is one more problem before we can use the OBJECT tag. Paranoid admins (and who can blame them?) have taken to stripping out the OBJECT tag (at least when it specifies the data="" attribute). At work, I am unable to see the examples, nor the right side menu bar in Tantek's log. Has anyone else observed this? I don't know how common it is, but I fear the worst.
- The fifth problem
2003-07-06 20:49:50 MikeyC Cacciottolo [Reply]
If you use text as the lowest nested element (as you should), eg:
<object type="video/mpeg" data="sunset.mpg">
<object type="image/jpeg" data="sunset.jpg">
Sunset in Hawaii
</object>
</object>
Then it shouldn't matter that a sysadmin strips the Object tag away as you would still get the fallback text which could include a link to download the data. So I really don't think stripping away the Object tag violates the spirit in which the Object tag was devised to be used.
Internet Explorer's inability to properly nest Objects has always been the major problem.
- The fifth problem
- Use of Conditional Comments
2003-07-03 21:30:26 MikeyC Cacciottolo [Reply]
Using conditional comments as described in the article will actually hide the nested Object from all browsers:
<!--[if !IE]>
<object></object>
<![endif]-->
Therefore, it should be constructed in the following way in order to hide the nested Object only from Internet Explorer. However, this method won't validate which means it can't be used in XHTML 2.0:
<![if !IE]>
<object></object>
<![endif]>
- Use of Conditional Comments
2006-04-09 08:19:33 allthegoodnamesaretaken [Reply]
I can't comment on xhtml but I've tested all the examples above as plain HTML and they don't work! However there is a syntax for 'down-level' (Microsofts' obnoxious label for browsers that aren't IE) CC's that works AND validates:
<!--[if gte IE 6]><!-->
Seen by all real browsers and IE 6. Validates as HTML 4.01 Transitional and possibly other doctypes
<!--<![endif]-->
Tested and working on Firefox 1.5, Opera 7.5, IE6, Konqueror and Lynx.
The only problem I've found with this code is that it confuses the syntax highlighter built into the CFML module for Eclipse (causing it to render the remaining page in comment green).
Thanks to Stu at cssplay.co.uk for finding this. I don't know where he found it but I'm grateful anyway. As usual the MS documentation was completely useless and even google failed to turn up much of value.
- Use of Conditional Comments
2003-07-04 03:17:18 Florian Bauer [Reply]
You can embed the conditional comments like this:
<!-- [if !IE] -->
<object></object>
<!-- <![endif] -->
- Use of Conditional Comments
2003-07-04 07:46:18 MikeyC Cacciottolo [Reply]
"You can embed the conditional comments like this:
<!-- [if !IE] -->
<object></object>
<!-- <![endif] -->"
Your example doesn't work. You can't use conditional comments in that manner.
- Use of Conditional Comments
2003-07-04 14:37:27 Florian Bauer [Reply]
I double-checked my example. It does indeed work, at least with the german version of IE 6. I have no idea whether this hack will work with any other version of IE. What version of IE did you use for testing?
- Use of Conditional Comments
2003-07-04 20:50:34 MikeyC Cacciottolo [Reply]
IE6 sp1 - english running on Windows NT &
IE6 sp1 - english running on Windows XP
Here is the exact example I used (and I just double-checked it):
<!-- [if !IE] -->
i can see this in Internet Explorer
<!-- <![endif] -->
- Use of Conditional Comments
2003-07-05 04:38:08 Florian Bauer [Reply]
That is strange:
Here is my example:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="de" lang="de">
<head>
</head>
<body>
<!--[if !IE]> -->
IE doesn't see this.
<!-- <![endif] -->
</body>
</html>
I checked this with ie6 on winxp, and ie5.5 on win98, both in the german version.
I also tried your example and the conditional comments do also work there.
strange...
cheers
Florian
- Use of Conditional Comments
2003-07-06 16:17:35 MikeyC Cacciottolo [Reply]
I just realized something else. The example we've been playing with thus far uses a transitional doctype as it doesn't validate using a strict doctype. Something about character data not being allowed there according to the validator.
XHTML 2 won't have a transitional mode (as far as I'm aware), so it seems that you can't use conditional comments anyways to deal with IE's broken Object support.
Please correct me if I'm wrong.
- Re: Use of Conditional Comments
2003-10-16 18:09:25 Lenny D [Reply]
"I just realized something else. The example we've been playing with thus far uses a transitional doctype as it doesn't validate using a strict doctype. Something about character data not being allowed there according to the validator."
XHTML does not allow character data at the <body> level. It must be within a block level element such as.
- Re: Use of Conditional Comments
- Use of Conditional Comments
2003-07-05 11:25:34 MikeyC Cacciottolo [Reply]
I've isolated the problem. Your original example was:
<!-- [if !IE] -->
<object></object>
<!-- <![endif] -->
Your follow-up example was (notice there is no space before the opening bracket of the if statement):
<!--[if !IE] -->
<object></object>
<!-- <![endif] -->
Your second example is indeed correct. Why do trhings have to be so confusing ;)
- Use of Conditional Comments
- Use of Conditional Comments
- Use of Conditional Comments
- Use of Conditional Comments
- Use of Conditional Comments
- Use of Conditional Comments
2003-07-04 00:38:36 bryan rasmussen [Reply]
conditional comments has always seemed sort of an ugly hack to me, although if the focus starts to shift from IE as the development target of choice to IE as a legacy browser then they become perhaps more useful.
- Use of Conditional Comments
2003-07-05 06:58:33 James Fuller [Reply]
+1 on that, and why build another processing idiom, when we have xslt;
legacy html
<html>
<body>
<img id="1" src="sample.jpg" alt="sample" width="100" height="100" />
</body>
</html>
migration stylesheet
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" version="1.0"/>
<xsl:template match="/">
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="img">
<object id="{@id}"
type="image/jpeg"
data="{@src}"
width="{@width}"
height="{@height}"/>
</xsl:template>
</xsl:stylesheet>
and of course we can build in logic to manipulate as per the "if" statements.
Personally, I see xhtml a perfect partner with xslt, and would like to see increased binding between the two.
cheers, jim fuller
- Use of Conditional Comments
- Use of Conditional Comments
