Lab: SWFObject

SWFObject, Flash and the z-index

Sometimes you might want your SWF to go under some page elements. This has always been a tough nut to crack for Flash developers, because the Flash Player always writes the SWF on the topmost layer of the page, regardless of z-index order. This is especially annoying for people who use CSS-based menus, such as the famous Suckerfish menu method.

The answer is to use wmode="opaque" combined with z-index positioning in your CSS. The CSS looks like this:

<style type="text/css">
<!--
/* set to lower number than suckerfish menu "#nav" */
#flashcontent {
  z-index: 2;
}

/* set to higher number than SWF */
#nav {
  z-index: 3;
}
-->
</style>

Setting wmode with SWFObject 2.0's dynamic publishing is a breeze; just add the parameter to the "params" object::

 <script type="text/javascript">
	
   var flashvars = {};
   var params = { wmode: "opaque" };
	var attributes = {};
	
   swfobject.embedSWF("/lab/_common/sample.swf", "flashcontent", "550", "400", "7", "/lab/_common/expressinstall.swf", flashvars, params, attributes);
</script>

Setting wmode with SWFObject 2.0's static publishing should be even easier:

  <object id="flashcontent" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" width="550" height="400">
    <param name="movie" value="/lab/_common/sample.swf" />
    <param name="wmode" value="opaque" />
   <!--[if !IE]>-->
    <object type="application/x-shockwave-flash" data="/lab/_common/sample.swf" width="550" height="400">
    <!--<![endif]-->
      <p>Please update your Flash Player</p>
    <!--[if !IE]>-->
    </object>
    <!--<![endif]-->
  </object>

The code as presented works fine in IE6 and Safari 3.1 (Windows), but doesn't work in Firefox 2.0. Turns out the outer object element targets Internet Explorer and non-Mozilla browser, while the inner object element targets Mozilla. This means the inner object needs to have a duplicate copy of the param element. From the SWFObject 2.0 documentation:

NOTE: The nested-objects method requires a double object definition (the outer object targeting Internet Explorer and the inner object targeting all other browsers), so you need to define your object attributes and nested param elements twice.

Here's the revised code:

  <object id="flashcontent" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" width="550" height="400">
    <param name="movie" value="/lab/_common/sample.swf" />
    <param name="wmode" value="opaque" />
   <!--[if !IE]>-->
    <object type="application/x-shockwave-flash" data="/lab/_common/sample.swf" width="550" height="400">
    <param name="wmode" value="opaque" />
    <!--<![endif]-->
      <p>Please update your Flash Player</p>
    <!--[if !IE]>-->
    </object>
    <!--<![endif]-->
  </object>

Working examples: static publishing | dynamic publishing (tested in Firefox 2, IE 6, and Safari 3.1 Windows).

Read this article for more background info.