Dump iframes and use object elements instead

Do you sometimes need to use iframe elements to inject content into sites you build? I do. Not very often, luckily, but it does happen. Usability and accessibility issues aside, doing so also forces me to use a transitional DOCTYPE, something I’d rather avoid.

There is an option, but it is of little practical use since it doesn’t work in Internet Explorer: the object element. Or so it was believed. The other day I came across Stuart Colville’s post No more iframes?. In the post, Stuart points to Aleksandar Vacić’s article Insert HTML page into another HTML page, which explains a very clever way of using an object element to insert an external HTML document into a page.

Aleksandar solved the problem by finding a value for the object element’s classid attribute that makes IE accept an external HTML document as the content of the object element. And it actually seems to work. Stuart discussed Aleksandar’s technique with a couple of colleagues and cleaned it up slightly code-wise. View Using an object Element instead of an iframe for a demo and explanation.

I haven’t tried this myself yet, but I’m sure I’ll find an opportunity to do so sooner than I’d like to.

Update (January 2010): The demo referred to above does not use conditional comments to hide the classid attribute from non-IE browsers, which causes the technique to fail in recent versions of Firefox. Using conditional comments as in Aleksandar’s article should fix that.

Posted on December 14, 2006 in (X)HTML, Browsers, Quicklinks

Comments

  1. Up until the point when I started using script.aculo.us (day after going to a Carson Workshop that Thomas Fuchs was doing), I’d use the occasional IFRAME for retrieving content from other pages - now having learnt about xmlhttprequest() I don’t see any logical reason for using iframe’s - they should die a quick but painful death!

  2. December 14, 2006 by siftee

    iframes are necessary in only one circumstance and for this reason they cannot die… as far as i know it is the only way to post a file () without a page refresh. I could be wrong (i’d love it if i was)

  3. Does invalid code in the page that is included make the page it is included in, also invalid? Because they say the page needs to be in Quirks mode, otherwise IE7 will show a border.

  4. Seems a lot of people wants to use the shorter syntax then the one I use. :) I intentionally separate the IE-only code from the standard-compliant one, because it proved to be easier in the long run. Especially when some of my friends/colleagues get to maintain it.

    I’ve invested a lot of time into preaching of standards use in the company and not using embed but double-object thingie was the toughest to push through. However, since I moved to this way of coding, from the old object in a object syntax, I had 0 “hey Alek, how to properly embed…” questions from any member of the team. It’s clear and easy to be macroed.

  5. Okke: no. The included page on my site (where I use this technique) is valid and standard-compliant.

  6. Eh…when my fingers are faster than my brain. :))

    No, the included page can be perfectly valid and in standard mode, but I intentionally use quirks mode because Kayak.com’s code is properly working only in such mode.

  7. One comment indicates that using the object tag does not appear to work in IE6 when you try to load a page from an external domain. If true, this technique wouldn’t be all that useful.

  8. I’ve come across the border bug in IE7 as well (I tested with iframes). If you use the proprietary (and invalid) “frameborder=0” attribute, IE7 will remove the border.

    After some more testing, it just got weirder. I wanted to sneak the attribute in through the DOM to pass validation, only to find that IE7 did not apply the frameborder attribute using setAttribute. After poking around, it seems it only applies using innerHTML.

  9. The main (and probably only) reason I have had to use iframes is for making a part of a document editable as in a WYSIWYG editor. I have tried using object elements for this in the past but it seems that the only current cross-browser solution is with the iframe.

    Until someone finds a way around this, it seems we’ll have to deal with iframes and transitional doctypes in these types of increasingly popular web apps.

  10. David G. Paul

    now having learnt about xmlhttprequest() I don’t see any logical reason for using iframe’s

    If some or all of your users don’t have JavaScript enabled, it would be logical to use iframes.

  11. It doesn’t work in IE when you change the security settings to disallow ActiveX controls. You also get a warning in the yellow/gold bar.

    Maybe you can use conditional comments to feed IE an IFrame and the rest an object. That way your page will still validate. It’s a lot of extra work.

  12. I don´t get it. Is the object element any better than an iframe except being able to use an a strict doctype? Is an object more accessible than an iframe? Please forgive me for not understanding this.

  13. December 14, 2006 by Roger Johansson (Author comment)

    David:

    now having learnt about xmlhttprequest() I don’t see any logical reason for using iframe’s

    Like Robert says, that will make you depend on JavaScript being enabled and browsers supporting xmlhttprequest.

    soxiam:

    One comment indicates that using the object tag does not appear to work in IE6 when you try to load a page from an external domain.

    That would indeed make it a lot less usable. I don’t know if it is correct.

    Greben:

    It doesn’t work in IE when you change the security settings to disallow ActiveX controls.

    Hmm. Not very good.

    Jens:

    Is the object element any better than an iframe except being able to use an a strict doctype? Is an object more accessible than an iframe?

    Since you asked I did some very quick testing, and it seems like the examples in the articles I linked to don’t work very well with screen readers or keyboard navigation. That would actually make object elements less accessible than iframes. Hmm. I’ll have to take a closer look.

  14. iframes are useful for the IE-specific rendering bug which causes select boxes to “shine through” an absolutely positioned element. I’m excited to try using object instead, perhaps the iframe hack coupled with conditional compilations is no longer necessary.

    Thanks for echoing this, Roger!

  15. Roger thanks for the heads up. Never heard of this solution, although there seems to be some drawbacks, it always helps to push the edge and maybe discover new ways of doing things. Shame about the possible accessibility issues.

    @John Hansen - no that would be a treat, as the environment I am currently working in as an issue with that bug fix. Don’t ask, weird production environment. But I’ll have to try doing something with this and see if it works better.

  16. December 15, 2006 by Jon Prins

    If you use this method to embed, say, a form in a page, does it look to the post action recipient as if it originated from your page, or the embedded page?

    This is one of the only situations I can think of where an iFrame really is necessary.

  17. but surely if Javascript is disabled it would be better to just have the page refresh?

  18. I’ve not tested the object method with screenreaders, but one thing that I did notice with using object with a local/relative file:

    <object data=”/template/example.html”>..

    is that Tab key access worked “as expected”, whereas when using a remote HTML source:

    <object data=”http://www.google.com/index.html”>..

    the tabbing functionality broke.

  19. I’ve HAD to go the Object route - like it or not - on my XHTML 1.1 site.

    It seems that Google’s ADSense uses iframes!

    So, on my XHTML 1.1 pages (I check for the browser’s access to that doctype via php, and feed the dummed-down XHTML 1.0 Strict to IE. I had to, as I serve as:

    Content-Type: application/xhtml+xml;)
    

    Anyway, This is what I do to get the Object tag used:

                <!-- begin google 180x60 firefox banner -->
                <div class="google-ff">
                    <?php if(stristr($_SERVER['HTTP_ACCEPT'],"application/xhtml+xml")) {
                        print "<object data=\"/ads/google-ff.php\" type=\"text/html\"></object>\n";
                        } else {
                    ?>
                    <script type="text/javascript"><!--
                        google_ad_client = "pub-5310110399308497";
                        google_ad_width = 125;
                        google_ad_height = 125;
                        google_ad_format = "125x125_as_rimg";
                        google_cpa_choice = "CAAQ_f-XhAIaCDgvi727fxoIKK2293M";
                        google_ad_channel = "";
                        //--></script>
                    <script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script>
                    <?php
                        }
                    ?>
                </div>
                <!-- end google 180x60 firefox banner -->
    

    Any thoughts on that?

    God Bless,

    Martin E.

  20. My code fragments above didn’t work as:

    http://daringfireball.net/projects/markdown/syntax#precode

    said it would?

    Anyway, here is the code frag again, using extended characters for the greater than/less than signs:

    <code>      
    <!-- begin google 234x60 banner -->
    <div class="google-ad234x60">
        <?php if(stristr($_SERVER['HTTP_ACCEPT'],"application/xhtml+xml")) {
            print "<object data=\"/ads/google-ad234x60.php\" type=\"text/html\"></object>\n";
            } else {
        ?>
        <script type="text/javascript"><!--
            google_ad_client = "pub-xxxxxxxxxxxxxx";
            google_ad_width = 234;
            google_ad_height = 60;
            google_ad_format = "234x60_as";
            google_ad_type = "text_image";
            google_ad_channel = "";
            google_color_border = "989876";
            google_color_bg = "EDEDE3";
            google_color_link = "616244";
            google_color_text = "647663";
            google_color_url = "7F7A83";
            //--></script>
        <script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script>
        <?php
            }
        ?>
    </div>
    <!-- end google 234x60 banner -->
    </code>
    
  21. January 25, 2007 by Roger Johansson (Author comment)

    Martin: Sorry about the preview messing things up. MovableType’s commenting system is a mess that I am unable to do anything about.

    Yep, AdSense uses iframes. A couple of years ago when I used XHTML here I used object elements for browsers that received XHTML. Your approach is slightly different, but looks interesting.

  22. Yes, interesting enough to give me a killer headache!

    It validates, though!!!

Comments are disabled for this post (read why), but if you have spotted an error or have additional info that you think should be in this post, feel free to contact me.