15, 2006

Flash, WMode, Scrolling, and Overflow:auto in Firefox

As any developer who has used flash in a webpage that contained overlays like lightbox or even drop down navigation menus will know, in its normal mode of operation Flash content will appear above all other layers on a web page. To allow flash content to be layered with other elements, you must set the WMode property to either    "transparent" or "opaque" (Transparent will allow content behind the movie to show through transparent areas.):


<param name="wmode" value="transparent">
<embed ... wmode="transparent" ...>

This works very well in Internet Explorer, but there are several problems in Firefox.

The first is an easy fix: If the flash content is contained in an absolutely positioned element, and that element has its overflow peoperty set to auto, the mouse events in the flash object respond as if the flash was positioned in the upper left hand corner of the page, no matter where it actually is. To fix this you can simply set the overflow property to none.

As long as your flash is on a page that does not need to scroll, that will fix the problem. However, if the page scrolls, mouse events will be offset by the scroll height of the page, rendering any flash that initially loaded below the fold inaccessable to the mouse entirely.

The fix

The solution to this problem is to dynamically create iframes to contain the affected flash content when viewed in Firefox. Iframed content will layer properly, and the flash will always be in the upper left hand corner of its framed document.

The following code relies on the availability of the jquery library and Michael Geary's DOM creation tool.


function iframeSwitch()
{
   //find flash content container and grab contents
   //(should only be object and embed tags)
   var container = $("#flash_content");
   var c = container.html();

   //get the size from the object element
   var object = $("object",container);
   var x = object.width();
   var y = object.height();

   //create the iframe element, hidden for now
   var frame = $.IFRAME({
      id:'graph_content_frame',
      frameborder:'0',
      marginwidth:'0',
      marginheight:'0',
      scrolling:'no'
   });
   $(frame).css('display','none');
   
   //attach the iframe to the document and remove the
   //old flash container element
   container.after(frame).remove();
   
   //set the size, open the iframe, and insert
   //the flash content.
   $("#graph_content_frame")
   .css('border','none')
   .height(y+'px')
   .width(x+'px')
   .css('display','block')
   .each(function(){
      this.contentDocument.open();
      this.contentDocument.write(c);
      this.contentDocument.close();
      
   });
}

Posted by tom at 11:44 | Comments (0)

All that work, so long ago

The last time I posted something on this domain was well over a year ago. I spent a month working on a redesign I used for five posts. Now I am going to be starting again, and with a default template no less. At least to start. But I wanted somewhere to write again. And with this new post comes a new topic. Quantumslip, as it was, if it ever is again, will live somewhere else. For now, this site will focus mostly on web development.

Posted by tom at 11:39 | Comments (0)