Stop flash from covering HTML content

Browse through a few developer forums and you will find lots of people pulling their hair out over flash content covering up their dropdown menus or modal windows.  The problem is especially bad in IE (surprise, surprise). The fix is actually quite simple as long as you can edit the embed code for your flash. The trick is to change the wmode parameter to either “transparent” or “opaque”.  You should do this for both the <embed> and <object> tags like this:

<object width="200" height="300" data="example.swf" type="application/x-shockwave-flash">
    <param name="quality" value="high" />
    <param name="wmode" value="transparent" />
    <param name="src" value="example.swf" />

The problem is you don’t always have the option of changing the embed code.  What if you’re developing a JavaScript widget and don’t have any control over how the flash is embedded?  The solution is more complicated than you would expect.  It turns out there are a slew of IE bugs around the <object> tag that escalate what should be a simple task into a real headache.  Basically you need to replace each <embed> and <object> tag with a cloned version that has had its wmode parameter fixed. Here’s how you do it:

<script type="text/javascript">

function fix_flash() {
    // loop through every embed tag on the site
    var embeds = document.getElementsByTagName('embed');
    for(i=0; i<embeds.length; i++)  {
        embed = embeds[i];
        var new_embed;
        // everything but Firefox & Konqueror
        if(embed.outerHTML) {
            var html = embed.outerHTML;
            // replace an existing wmode parameter
                new_embed = html.replace(/wmode\s*=\s*('|")window('|")/i,"wmode='transparent'");
            // add a new wmode parameter
                new_embed = html.replace(/<embed\s/i,"<embed wmode='transparent' ");
            // replace the old embed object with the fixed version
        } else {
            // cloneNode is buggy in some versions of Safari & Opera, but works fine in FF
            new_embed = embed.cloneNode(true);
            if(!new_embed.getAttribute('wmode') || new_embed.getAttribute('wmode').toLowerCase()=='window')
    // loop through every object tag on the site
    var objects = document.getElementsByTagName('object');
    for(i=0; i<objects.length; i++) {
        object = objects[i];
        var new_object;
        // object is an IE specific tag so we can use outerHTML here
        if(object.outerHTML) {
            var html = object.outerHTML;
            // replace an existing wmode parameter
                new_object = html.replace(/<param\s+name\s*=\s*('|")wmode('|")\s+value\s*=\s*('|")window('|")\s*\/?\>/i,"<param name='wmode' value='transparent' />");
            // add a new wmode parameter
                new_object = html.replace(/<\/object\>/i,"<param name='wmode' value='transparent' />\n</object>");
            // loop through each of the param tags
            var children = object.childNodes;
            for(j=0; j<children.length; j++) {
                if(children[j].getAttribute('name').match(/flashvars/i)) {
                    new_object = new_object.replace(/<param\s+name\s*=\s*('|")flashvars('|")\s+value\s*=\s*('|")[^'"]*('|")\s*\/?\>/i,"<param name='flashvars' value='"+children[j].getAttribute('value')+"' />");
            // replace the old embed object with the fixed versiony


This solution is adapted from code I found on QIndex. Hopefully this version is a little cleaner and easier for people to find.

Note: There is also a jquery version of this code, complements of José Nobile.
  • Pingback: Интересното от 17.08.2009 |

  • I Write a more litte javascript using jQuery, working better, dont use regular expression.

    Key Features:

    Only include the script in any webpage, it change/add the wmode to transparent, to embeds and objects
    Work with or without jQuery included. (if is not jQuery, it is included using Google CDN Service (minimized and Gziped) ->
    Compatible with other libraries (ej Mootools) using jQuery.noConflict();
    Work at Firefox 2.0+, Internet Explorer 6+, Safari 3+, Opera 9+, Chrome 1+
    Use Dom Ready, is possible to include the script at head of html.

    The Source is available for download from:

    A Minimized version:

    The version minimized and Gziped is only 637 Bytes !

    Or the Source:
    function LJQ() {
    var sc=document.createElement('script');
    sc.src=';; = 'script1';
    sc.defer = 'defer';
    window.noConflict = true;

    if(typeof (jQuery) == "undefined") {
    if (window.addEventListener) {
    window.addEventListener('load', LJQ, false);
    } else if (window.attachEvent) {
    window.attachEvent('onload', LJQ);
    else { // JQuery is already included
    window.noConflict = false;
    window.setTimeout('window.fix_wmode2transparent_swf()', 200);

    window.fix_wmode2transparent_swf = function () {
    if(typeof (jQuery) == "undefined") {
    window.setTimeout('window.fix_wmode2transparent_swf()', 200);

    // For Internet Explorer
    jQuery("object").each(function (i) {

    var algo = jQuery(this).context.attributes;
    var str_tag = '<OBJECT ';

    for (var i=0; i < algo.length; i++)
    str_tag += algo[i].name + '="' + algo[i].value + '" ';

    str_tag += '>';

    var flag = false;

    jQuery(this).children().each(function (elem) {
    if (jQuery(this).attr("NAME") == "wmode") {
    str_tag += '<PARAM NAME="' + jQuery(this).attr("NAME") + '" VALUE="transparent">';
    str_tag += '<PARAM NAME="' + jQuery(this).attr("NAME") + '" VALUE="' + jQuery(this).attr("VALUE") + '">';

    str_tag += '<PARAM NAME="wmode" VALUE="transparent">';

    str_tag += '</OBJECT>';

    } );

    // For Firefox Browser
    jQuery("embed").each(function(i) {

    • Nice. I was using this on a javascript widget and didn't have the privilege of using jQuery. Thanks for sharing.

      • I was wondering if there was a benefit to using the jQuery version vs the JS version. I'm currently running a drupal site and I could support either or.

        Side question, if you think I should use the jQuery version. Drupal already has jQuery.js in it, so how can I prevent the jquery version from being downloaded again? Do I just remove the "LJQ" function?

        • Use the jQuery version if you've already taken the hit of loading it in. It already handles checks to see if jQuery is defined before loading it in.

  • Ok, you can include the script in any webpage or javascript without jQuery already included and the script auto include jQuery and noConclift mode, it may be perfect compatible with you javascript widget 🙂

    • Sure, I just don't want to add a javascript library on other people's sites when it's not necessary. My widget is 8K. JQuery would add 50k. It's not a good trade-off to add 50k to save 1k. Performance matters a lot to me as people are very sensitive to how much a widget slows their page down. The jQuery solution is great if you've already taken the hit on including the library.

  • mmm, you comment is good, if you widget is only 8K is better a solution using "native" javascript.

    but, only two observation: Google CDN (Content Delivery Network) put the hosted content at GZiped, how the jQuery library, the version hosted at
    is only 19K (Gziped), the time to load the file and process is beetween 120ms and 500ms (0.5 seconds)

    Dont try: if (embed.outerHTML) {

    Firefox had not outerHTML, is safe remove these conditional.

    • Yeah, the Google CDN is good. Of course, the biggest advantage is the increased chance of getting a local cache hit. The more people use Google, the better the service becomes for everyone. Eventually those libraries are just going to be built into browsers.

  • fractalbit

    I wish i had discovered this earlier. A drop down menu for navigation was hiding behind a flash. You can imagine how angry the users get when they cannot navigate to your site. Now imagine their anger considering the fact that the flash movie blocking navigation was a… 720×90 advertisment! Unfortunately i did not had direct control of the advertisment. I had to contact the advertisment provider and spend hours on the phone trying to explain them how and why they should set the wmode of the flash file to transparent 🙁

    Next time this happens to me, i will try your script. Many thanks!

  • Hello, the code above doesnt work, since there are missing some escape sequences in the regexps 🙂 (Meanwhile its possible to use code from this page's embedded JS)

    But this is so great sollution, i was trying to find one really hard. Maybe you can add some keywords to article, these are the phrases I GOOGLEd up:
    jquery hide flash objects, jquery hide flash when overlaying, jquery overlay on top of flash, jquery remove flash, jquery remove FLASH object param embed (the last one led me to your site :D)

    • Sorry about that. My code coloring plugin has a bad habit of slaughtering regular expressions. It should be fixed now.

      I've added a bunch of keywords to try and make it easier for people to find in Google, along with a direct link in the post to José's jquery version. It took me a long time to figure out this solution, so I want to save as many people as I can from that pain.

  • Brendan

    Testing this cool commenting feature.

  • My comments are a widget that you can get from I highly recommend it.

  • My comments are provided via a widget from I highly recommend it.

  • A simular take to solving the problem using jQuery:

  • Beautiful. Thanks for sharing.

  • Tried every code posted here… none seem to be working in IE8.

    I'm trying to fix embedded videos (vimeo and youtube) without manually adding wmode to the embed code.

    Can anyone provide a working demo?

    • Is it giving you an error or failing silently? I don't have a computer w/ IE8 handy to check it out myself.

  • Failing silently.

    However, the one that does work across all browsers for me is your original reference link:

    • Very weird — especially since I borrowed so heavily from that example. I'll grab a PC later and take a look. Thanks for letting me know.

  • I found the problem, is very rare, el code from vimeo using object + embed for show flash in IE, but in Firefox use object + embed, I dont understand very good, but it see in developers tools in IE and in Firebug in FF.

    The problem in firefox, is when I tried to execute the code for fix in IE, it to do regenerate the object, but without embed, obly params.

    if comment the part for Internet explorer, it working in FF and IE, pero only for vimeo videos embebeds.

    These "object" from code to embeed the swf in video is from type (object HTMLGENERICELEMENT) the normal object (with codebase and classid) is from type (object).

    The solution is detect the HTMLGENERICELEMENT and to end the funciton. I tried this.nodeType, this.nodeName, typeof this, but only a alert(this) show it.

    Now I'm working in this.

  • Many fixes and patch applied to my code.

    Finally I searched a embed into the objects, if detected, it is cloned, after is changed (or added using setAttribute) wmode param to the clone, the clone is inserted after the original, and the original is deleted, the object parent of the embed was not alter, only the embed.

    El code was updated in

    And a test (Vimeo video and div with position fixed) suggest by Brian is in:

    • Tânia B Nielsen

      You just saved my life and maybe my job. Thank you!

    • Hi Jose, I've tried your solution and found out that the line 'this.attributes' will not work on IE7.
      I think it 's IE7 fault and has nothing to do with your implementation. I would like to know the solution if any. Thanks.

      • I tested in IE 7 and it worked.
        I checked in MSDN, and attributes property exits in all IE versions
        I checked in W3C and is part of DOM level 1

        Do you can give me what error appear in your IE 7?

        • Hi Jose, Sorry for the late reply. I've made a sample at
          You can take a look at the JS source codes of the page.
          By right, IE7 will echo some attributes. It doesn't echo in my IE7.

        • Tânia B Nielsen

          Just realized I have the same problem =/
          IE7 seems to think all the values to all the attributes of the object are null
          The flash just disappear
          Don't know what to do

    • Bernardo

      Hy, in Ie8 it's not working well. Any ideas?

  • frank

    nice.. just what i needed.. brilliant..

  • thanks for this script it help me very much,…

    I just have a bug with IE 6 and 7,..

    so I implemented like this

    <!–[if !IE]>–>
    <script type="text/javascript" src="js/fix_wmode2transparent_swf.js"></script>

    it work for my overlay problem over a vimeo video

    Thank you

  • Nino

    Thanks for the great insight. Worked quite well…

  • Shlomo

    You're amazing.
    I spent days trying this in DOM, and was only successful with the embed tag (Firefox, etc) and not the object tags (Internet Explorer). Don't know why. You're way of just replacing the html works even for Internet Explorer.


  • nick lankester

    I also have played with all the scripts on this page..
    The code in the post that is from José Nobile (5 posts before this one) works on my page in Firefox but not in IE8…
    No change is registered to the embedded flash movie's wmode parameter…

    anyone got this to work in IE7/8?

    I can post a link to the page I'm working on if anyone wishes to explore why it isn't working.


    • José Nobile has been quite responsive to bug reports. You may want to include him and see if he has any thoughts as well.

  • Dmitry Medvinsky

    I might be a bit late in here, but in the line 47 there should be

    new_object = new_object.replace…

    instead of

    new_object = html.replace…

    • you sure? it's been a while since i wrote this, but looking at it again, it doesn't look like new_object is defined as anything until after that line. i don't think you want to do a replace on an empty object.

      • Dmitry Medvinsky

        Line 47 is the line inside the for loop (for(j=0; j<children.length; j++) this one).

        new_object is definitely defined (sorry the the tautology) in the line 39 or 42, in the if/else block (at least one branch of it gets executed, since there is an else statement). 🙂

        So the assignment in the line 47 kills all the effort of adding [param name="wmode" value="opaque"] stuff in the object.

        • you're right. good catch. i was looking at the wrong line. i'll fix it now.

          • Dmitry Medvinsky

            Btw, thanks for the post. 🙂

          • sure. glad it was helpful. i've updated my post w/ your fix.

  • Lisa

    Thankyou, thankyou, thankyou. Been trying to fix this problem for the best part of the day. Plugged your script in and it works wonderfully.

  • bandcoach

    Strangely, leavingthe close object tag out create a similar problem in ie but not firefox or opera.

    As soon as I added the close object tag, this fixed it; no need for wmode to be set or anything else.

  • excellent! thanks so much, that was driving me nuts!

  • jrt324

    it does't working in IE 6

  • Woot! I found your solution an hour ago, and it's now a proud part of AdGrok's GrokBar… Thanks!

    • Awesome! Always love to hear stories from people who use my code. Love what you're doing with AdGrok. We should chat about getting you set up with Torbit too. 🙂

  • I have a menu that is being killed by an ad so need this fix, however, I don't know if rewriting the HTML may grab another ad ad or re-embed it and bugger up the impression counts etc, before I run with this, anyone had any experience?

  • krishna

    Thank you so much. You saved my day.

  • With prototypeJS, I'd do:

    if ( Prototype.Browser.IE ) {
    $$('object').each(function(s) {
    if ( s.down('param[name="wmode"]') ) {
    s.down('param[name="wmode"]').writeAttribute('value', 'transparent');
    } else {
    var newObject = s.clone();
    s.childElements().each(function(j) {
    newObject.insert({bottom: j});
    var newParam = new Element('param', { 'name': 'wmode', 'value': 'transparent' });
    newObject.insert({bottom: newParam});
    s.up().replaceChild(newObject, s);
    } else {
    $$('embed').each(function(s) {
    var newEmbed;
    newEmbed = s.clone();

  • boiii

    Thanks for the excellent blog, saved my butt!!!