Using <object> instead of <iframe>
2008 Dec 31, Information Technology
Last updated: 2010 Aug 20
The <iframe> element is not valid beyond HTML 4.1 / XHTML 1.0 Transitional. To achieve compliance with the XHTML 1.0 Strict DTD you must use the <object> element instead. In my opinion you needn't worry about falling short of XHTML 1.0 Strict if the only thing holding you back is your judicious use of an <iframe> to embed content. But if you're a stickler about such things, or if you're beholden to sticklers, you need to abandon <iframe> for the time being.
Yes, perhaps only for the time being. It seems that <iframe> will be fully valid once again in HTML5. This suggests that W3C perhaps regrets insisting on <object> to the exclusion of <iframe> in XHTML 1.0.
Maybe it wasn't such a bad idea, though. Firefox, Safari, Chrome, and Opera offer robust support for the use of <object> to embed external HTML content. If everyone used one of those browsers, perhaps <iframe> would indeed be superfluous. There is a certain elegance to using a generic <object>, with its type set as appropriate, for any kind of embedded content, after all. And even Internet Explorer, in its most recent versions, is beginning to support <object> to a large extent. So maybe W3C was right to nudge <iframe> towards obsolescence with XHTML 1.0. Maybe W3C is erring now, with HTML5, in capitulating to the entrenched <iframe> interests.
I know not—and care not.
The question at hand is this: How do you embed one web page within another in a manner that complies with the XHTML 1.0 Strict DTD and works well for all the major browsers, including IE?
These days I'm using and recommending the following markup, verbose but effective:
<!--[if !IE]>-->
<object data="http://www.google.com/" type="text/html" style="width:30em;height:10em;">
<p>Sorry. This content cannot be rendered (non-IE object).</p>
</object>
<!--<![endif]-->
<!--[if gte IE 8]>
<object data="http://www.google.com/" type="text/html" style="width:30em;height:10em;">
<iframe src="http://www.google.com/" type="text/html" style="width:30em;height:10em;">
<p>Sorry. This content cannot be rendered (IE >=8 object/iframe).</p>
</iframe>
</object>
<![endif]-->
<!--[if lte IE 7]>
<iframe src="http://www.google.com/" type="text/html" style="width:30em;height:10em;">
<p>Sorry. This content cannot be rendered (IE <=7 iframe).</p>
</iframe>
<![endif]-->
This markup makes use of a Microsoft invention called Conditional Comments to introduce IE accommodations within the confines of HTML comments. Other browsers, and the XHTML validator, will ignore these accommodations.
The gist of my approach is to use an XHTML 1.0 Strict-compliant <object> to embed content for good-guy browsers—and to satisfy the validator. But for IE, in a version-sensitive manner, I use either <object> or <iframe>. I make no attempt to use <object> with IE versions below 8 as I have no confidence in those versions' support for <object>. Specifically, those early IE versions do not always respect fall-back content nested within <object>, nor do they behave consistently in embedding local (same-domain) vs. remote (different-domain) files. IE 8, by contrast, behaves well and consistently for the most part, though it balks at loading remote files. Thus for IE 8 I use a nested <iframe> to handle the remote-file case.
The markup above is XHTML 1.0 Strict-compliant and embeds either local or remote files. I intend it is a general-purpose approach for embedding one web page within another.