Embedding Flash While Supporting Standards (and without javaScript)
An even better improvement to the Flash Satay and Flash Javay methods
I’ve been looking at the Flash Satay method of maintaining valid markup using flash (the <embed> tag commonly used for non-IE browsers is no longer supported by current versions of HTML and XHTML). It always seemed a little wacky and time consuming to have to load your flash content into a container .swf and was not appealing to me at all. The Flash Javay method tries to address this problem, but I never liked the idea of using that much javaScript either. I mean, haven’t we spent the past few years trying to come up with a Flash detection that doesn’t use javaScript? The Javay method seems like a step backward, not forward.
Before I share my newly found solution to both problems, let me share this little newly found secret about Internet Explorer that might be useful to you in many other applications other than embedding Flash. Using the following code will only show up in Internet Explorer browsers:
<!--[if IE]>You are using IE!<![endif]-->
Now that we’ve got that out of the way, lets discuss what I’ve dubbed the Flash Gillay method. (Because everyone who comes up with a modified version of the Satay method has given it a new name, I’ve decided to name this one after myself in hopes for fame and fortune!) The general idea is to use the <object> tag exactly as it is commonly used, but to replace the <embed> tag with the Satay formatted <object> tag. Putting the Satay format inside the common format will work fine for browsers that would otherwise need the <embed> tag without any other code to help it out. For example, the following code will work in FireFox/Mozilla/Netscape without any problems:
<object
classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
codebase="http://download.macromedia.com
/pub/shockwave/cabs/flash/swflash.cab#version=6,0,0,0"
width="400" height="300" id="movie" align="">
<param name="movie" value="movie.swf" />
<object type="application/x-shockwave-flash"
data="movie.swf" width="400" height="300">
</object>
</object>
Notice that there’s no need for a container movie.
Now of course, IE browsers are going to CHOKE on this trying endlessly to load the second object. Here’s where the above mentioned trick comes in handy. Without using any Javascript at all, we can hide the second object from IE browsers by using the following:
<object
classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
codebase="http://download.macromedia.com
/pub/shockwave/cabs/flash/swflash.cab#version=6,0,0,0"
width="400" height="300" id="movie" align="">
<param name="movie" value="movie.swf" />
<!--[if !IE]> <-->
<object type="application/x-shockwave-flash"
data="movie.swf" width="400" height="300">
</object>
<!--> <![endif]-->
</object>
And as for the need for an alternate image or text to appear if Flash is not installed, you can now take it a step further and be even more standards compliant than the Satay method by making your alt text readable by screen readers:
<object
classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
codebase="http://download.macromedia.com
/pub/shockwave/cabs/flash/swflash.cab#version=6,0,0,0"
width="400" height="300" id="movie" align="">
<param name="movie" value="movie.swf" />
<!--[if !IE]> <-->
<object type="application/x-shockwave-flash"
data="movie.swf" width="400" height="300">
Description of Flash Content for screen readers
</object>
<!--> <![endif]-->
<!--[if IE]>
Description of Flash Content for screen readers
<![endif]-->
</object>
Notice the use of <–> and <!–> to trick non IE browsers into thinking that their respective lines end the comment and continue to render what’s inside the IF statement.
Now you can use the latest recommended Flash detection methods making it un-necessary to have your alt content point to a flash download page.
I have tested this method on IE 6.0, IE 5.5, Firefox 1.0, Mozilla 1.5, Netscape 7.0, Opera 7.1, Safari 1.0.2, IE 5.2 Mac, and yes, even Netscape 4.8. If you see any flaws in this method, I’d love to hear about it via email (I apologize for the lack of commenting capabilities on this blog, I’m still working on it).
This method can be seen in practice at http://www.gilluminate.com/
(12-21-2004 NOTE: Thanks to Stephen Rider for pointing out to me that about 8 months prior to this blog this method already existed as the Hixie Method. I maintain that I wasn’t aware of the Hixie Method at the original writing of this blog and apologize for the repeat.)
(01-17-2005 NOTE: If you plan to use the SetVariable command, you can still use id=”" for the IE version but you should use name=”" for the other version.)
(02-01-2005 NOTE: Comments are now turned on.)
(05-17-2005 NOTE: For information on why this method is more standards compliant than the Satay method, see the W3C Rules for rendering objects. Also, if IE followed these rules completely, they would not choke on the inner object tag, but only render the outter, and there would be no need for the extra IE only code.)
December 8th, 2004 at 5:08 am
I did have some issues with validation due the tags, but just experimenting with deleting those lines, it STILL works in IE7. (not sure about older version of IE, but at least it works in all of the most current browsers!
Thanks again for saving the day!
Sincerely,
~Greg
December 8th, 2004 at 5:08 am
December 8th, 2004 at 5:08 am
February 2nd, 2005 at 1:23 am
Waqas, this method assumes that Flash Player plugin is not installed on the machine of the person using the screen reader. The alt text will only appear if Flash is not present. See my previous entry to remove your own Flash plugin for testing with JAWS.
February 25th, 2005 at 1:49 am
I had been planning on making Flash navigation objects for a large web site I’m planning, the benefits being that I could replace all the navigation code in each html file with the swf object code, and when I need to update the navigation I do it in just a couple of swf files, not thousand of html files. But, when I read Waqas comments about accessibility, I knew this approach wasn’t going to work. But, I’ll be able to use your solution for the nonessential flash elements of my site.
I was fortunate enough to come across an accessible JavaScript navigation solution that imports styled html lists so that I will only need to maintain a few files and still be accessible. See the demo of this particular feature here http://www.udm4.com/demos/extension-import.php
March 2nd, 2005 at 12:44 am
..and what about
<!–[if IE]>
<object classid=”…”>
<![endif]–>
<!–[if !IE]> <–>
<object type=”…” data=”…”>
<!–> <![endif]–>
<param />
<param />
<p>Only one alternative for IE and other</p>
</object>
March 2nd, 2005 at 1:00 am
Excellent suggestion! I just tested it in the same browsers and still works. I like the idea that there’s only one set of params and alternative text.
Why didn’t I think of that?
March 4th, 2005 at 11:56 pm
I think, it may be even more elastic
Try to test (I didn’t) something like this
<!–[if IE]>
<object classid=”…”>
<param name=”forIE” />
<p>IE alternative</p>
<![endif]–><!–[if !IE]> <–>
<object type=”…” data=”…”>
<param name=”forNotIE” />
<p>NotIE alternative</p>
<!–> <![endif]–>
<param name=”forALL” />
<p>Alternative for all</p>
</object>
So, eg. <param name=”movie”.. we may add only for ie
We may do various combinations of params and alternatives.
Btw. some time ago I tested one [if] and a small trick with the <script> element…
http://www.blatek.co.uk/blateksatay/
March 18th, 2005 at 11:49 am
Has anyone had any success using this method and SetVariable() with Safari on the mac?
March 19th, 2005 at 4:08 am
Try this method Greg.
March 30th, 2005 at 8:06 am
So does this mean that i can use flash in my wordpress templates now?
April 20th, 2005 at 4:56 am
Tongue and Groove reader Shannon pointed out that using BlaTek’s method will cause IE to render an extra “<![endif]–>” when Flash is not present. To fix this little bug, just use 3 dashes “<![endif]—>” to end the “<!–[if IE]>” statement. Shannon also pointed out that the alternate text will not appear in Safari (Mac) if Flash is not present, which is also a problem on Macromedia’s own site. Based on comments in the page source, Macromedia appears to be using the Satay method, which means it’s not just the Gillay method that has this Safari issue.
May 24th, 2005 at 7:43 pm
Though it seems nice, the 3-dash approach makes the page invalid when validated against W3C validator.
May 25th, 2005 at 1:21 am
If you are concerned about W3C validating it, use a character other than the dash to solve it, such as “<![endif]x–>”. The idea is the same and W3C won’t complain about it.
June 4th, 2005 at 8:19 am
Thanks.
October 2nd, 2005 at 2:05 am
I have a 100% perfect method that works in *ALL* standard browsers (mozilla, netscape, firefox, opera, konqueror, safari, etc) in all operating systems including IE 100% and it is 100% perfectly XHTML strict valid! much better than any other method i saw on any other website except my website! even if browsers doesn’t understand the IE’s <!–[if IE] and <![endif]–> comments! and without using any JavaScript! and no container .swf! it’s simpler than your method so I won’t tell you that because it’s tricky to figure it out by yourself! that’s very close to my method but that’s not the perfect method!
October 3rd, 2005 at 1:13 am
Gee, thanks for letting us know. Your contribution to society is Impeccable.
October 20th, 2005 at 6:31 am
I’m not very experienced with the ins and outs of this stuff, so if you could gimme a hand, i’ll love you forever… I’ve implemented your method from this article, but I’m trying to use SetVariables. I’ve set the first object tag’s “id” attribute, and the second one’s “name” attrib, to the same thing – then I have my javascript up the top:
<script type=”text/javascript”>
<!–
window.onload=window.document.getElementByID(”title_menu”).SetVariable(”currentPage”, “home”);
// –>
</script>
But I get an error in IE (object doesnt support this property or method) and nothing at all in firefox.
A little help with setvariable and the object’s IDs would be appreciated!
Again, thanks for your method!
October 20th, 2005 at 7:45 am
Owen, Don’t use getElementById, rather just put the name as such:
window.onload=window.document.title_menu.SetVariable(”currentPage”, “home”);
November 20th, 2005 at 1:16 pm
November 20th, 2005 at 5:46 pm
November 21st, 2005 at 2:29 am
The site your name links to in your post works fine for me in FFmac, FFPC, and IE5mac. are you sure it’s not an issue with the setup of your browsers? Do you have a current version of Flash installed?
Check to see if this page works in all browsers:
gilluminate.com
November 29th, 2005 at 9:38 am
Dan
November 29th, 2005 at 9:47 am
November 29th, 2005 at 1:00 pm
By the way, the <!–[if IE]> “hack” for CSS is actually the way that Microsoft recommends doing it.
December 7th, 2005 at 8:07 pm
Thanks a lot. This is the best technique I have seen for embedding flash. Those conditional comments are great for IE-win only hacks.
December 21st, 2005 at 1:34 am
I have noticed that in Firefox (v1.1 and 1.5) if I have many flash elements loading on a page and try to call the SetVariable function from body onLoad I get the following error: “Error calling method on NPObject!” I have since worked it out that this is caused when the call to the flash movie is done before the movie is loaded. To rectify this, I have simply added a setTimeout call to the javascript so that the function is called 1-2 seconds after the page has loaded, but I suppose you could add something into the movie to say it has loaded. I just thought someone might like to know this – and seeing as this board came up quite highly on google when I was trying to fix this issue I thought I would post it here!
December 24th, 2005 at 1:04 pm
This method does not seem to work on asp pages. I receive a VBScript error: an OBJECT tag cannot be placed inside another OBJECT tag…
December 24th, 2005 at 1:06 pm
This method does not seem to work on asp pages. I receive a VBScript error: an OBJECT tag cannot be placed inside another OBJECT tag…
February 22nd, 2006 at 2:44 am
IE6 supports using <object> without the ActiveX attributes (classid and codebase). Remove those and duplicate the <param>s as attributes in the <object> and you have something valid without needing the <!–[if IE]–> hack. **Tested in IE6.0, FF1.x and NN 7.2 (all Win XP) and IE5.2, FF1.5 and Safari 1.3 (all OS X)**
Also, SetVariable now works in Firefox 1.0 and Netscape 7.2 (possibly earlier) on Win. OS X is still a problem: so sez Mozilla. You won’t need the name=id bit either, just the id.
February 22nd, 2006 at 10:23 pm
Thanks in advance.
June 3rd, 2008 at 3:00 am
June 13th, 2008 at 10:52 pm
Alternative text Mozilla
Alternative text IE
June 13th, 2008 at 10:54 pm
Alternative text Mozilla
Alternative text IE
June 13th, 2008 at 10:56 pm
June 2nd, 2009 at 5:04 am
June 2nd, 2009 at 3:21 pm
http://en.wikipedia.org/wiki/Conditional_comment