Web dev

Insert HTML page into another HTML page

…or what to use instead of iframe in XHTML Strict pages.

I have added some kayak.com ads the other night, to the archive pages related to traveling. These ads are actually full-featured search snippets that allows you to directly search kayak.com database. Very handy things.

Sadly, they are written the old-fashion way, with quirks mode in mind, and worse yet - they are writing nested table tag soup directly into the page - no iframe thingie, like Google AdSense is doing. Thus, when my CSS files got applied to it, the snippet fell apart.

Luckily, the snippet always opens a new window, thus I quickly coded in an iframe in which the snippet is displayed. Which was all dandy…apart from the fact that my pages are XHTML 1.0 Strict, in which iframe is banned element. Jolly.

Correct way to include another HTML page into another is by object. The element which only purpose is to insert any foreign object into nice and structured web page.

The standard way of coding an object element is to use appropriate MIME type and add the foreign object’s URL. Naturally, this does not work in IE6 (nor IE7) so I had to look for the infamous clsid value for text/html.

This proved to be quite a task, as I could not find any reference for that and after trying for 10 minutes I gave up and opened regedit, found the clsid branch and started arrowing-down until I found what I needed. After that, it was easy:

<!--[if IE]>
<object classid="clsid:25336920-03F9-11CF-8FD0-00AA00686F13" data="some.html">
<p>backup content</p>

<!--[if !IE]> <-->
<object type="text/html" data="some.html">
<p>backup content</p>
<!--> <![endif]-->

This worked like a charm, but in IE (both 6 and 7) it shows with an ugly border and scrollbar, even though the content itself was less than the width and height of the object element. It turned out that I need to specify this in the included page:

<body style="border:0;overflow:visible">

With this, you get seamless integration of external .html (or .asp or .php or whatever) into current web page.

[update, Nov 24th] Looking at the code, above, I think that p with the backup content is not really necessary. That would be displayed if for some reson the object could not be displayed. But the object data handler is the browser itself, not some external plugin, thus it is always present. Just object is enough (thus the strike through line in the example above).

[update, Nov 28th] Brad Wright chimed in with a valid argument that object may not be supported in all user agents. Backup content should be used.

Update, June 5, 2008: This post turned to be a hit. I never intended it to be a solution to everything, only to a particular problem I had at the time (I’m not even showing kayak.com ads anymore).

A lot of people add comments that the scrollbar-fix is not working. Note that included page in my case was non-standard tag-soup page, thus the two given styles somehow resolved my issue, without any promises it will work in all cases.

A lot of issues came up in comments for which I don’t have a solution (of the top of my head) nor time and incentive to investigate further. If I ever do, I’ll write it up. In the mean time, you’re on your own.

Translated to: Brazilian-Portuguese (by Mauricio Samy Silva).