File Under: Multimedia, Web Standards

Use Web Standards With Flash

It’s everywhere I turn. The cry is impossible to escape. I hear it shouted from the mountaintops with thunderous urgency: “Web Standards! Adhere to them and everything will be good.”

Web standards are understandably necessary, and I use them all the time in my own work, as should you. But is there still a place for Flash in this new standards compliant world? The answer is yes, of course.


Contents

  1. Embed versus Object
  2. JavaScript to the rescue
  3. Introducing sIFR
  4. How and when to use sIFR
  5. Putting sIFR on the page
  6. Achieving Perfect Harmony

The Standards-Compliant Flash Object of Desire

I find that my Flash work of late has been on smaller things — individual components that fit into larger XHTML/CSS sites rather than the previous norm of entire user experiences built with Flash. I, for one, welcome this change. I may be a Flash developer, but that doesn’t mean I want to visit websites built entirely with Flash.

True, there are still many big name companies out there that want “edgy” websites built using Flash. Increasingly, these high-profile websites are realizing that the search-ranking advantages of an XHTML/CSS website often outweigh the so-called “edginess” of a pure Flash website.

Let’s say, for example, that you’re a site developer using standards compliant XHTML. Some Flash developers have just delivered you a small, lightweight MP3 player written in Flash. The advantage of having an MP3 player built in Flash is that it can be embedded within an XHTML page. The user can listen to songs and have the same rich user experience offered by a stand-alone media player, all without leaving that particular page. Great, right? It would be, but it’s your job to integrate this MP3 player into the XHTML environment that makes up the rest of the site.

The rest of the site is entirely standards compliant code. You’ve even validated all the URLs against the W3C validator. You’ve spent considerable time working around the intricate browser quirks. In short, the code works in every browser and is all valid XHTML. Beautiful.

Now, lets throw the Flash monkey wrench into the works and see what happens.

Embed versus Object

Let’s say your Flash developers have sent you an .fla file and left all of the embed code up to you. You open the .fla in Flash and publish an .swf file. You also publish an HTML file, which is ridiculously easy. Just check the “Publish HTML” box and Flash does the rest. You end up cutting and pasting the results out of your newly minted HTML file into your existing XHTML page. The code Flash gives you looks something like this:

<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000"

codebase="http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/

swflash.cab#version=7,0,0,0" width="550" height="400" id="myMovie"

align="middle">



<param name="allowScriptAccess" value="sameDomain" />

<param name="movie" value="myMovie.swf" />

<param name="quality" value="high" />

<param name="bgcolor" value="#ffffff" />

<embed src="myMovie.swf" quality="high" bgcolor="#ffffff"

width="550" height="400" name="myMovie" align="middle"

allowScriptAccess="sameDomain" type="application/x-shockwave-flash"

pluginspage="http://www.macromedia.com/go/getflashplayer" />

</object>

Ugly but functional. Except … except now your site doesn’t validate with the W3C validator. In fact, your code is no longer standards compliant. Why? Well the W3C’s XHTML specifications don’t allow the <embed> tag. But Netscape-flavored browsers need the <embed> tag. To understand why the <embed> tag wasn’t included in the specification, we need to look at the history of the <embed> tag.

Dreamed up by Netscape long ago in a galaxy far away?. Actually, they just made it up out of nowhere. Supposedly, they did so to provide a generic method of dealing with the proliferation of plug-in technology circa 1998. Fortunately, the days of a zillion plug-ins are gone. Flash alone seems to have survived the plug-in wars (Okay, there are some others, but they aren’t relevant here). In Netscape’s thinking, the <embed> tag would have been a generic solution. Its parameters would tell the browser how to behave using name/value attributes. Neither Microsoft nor the W3C liked this idea. They both liked the <object> tag, which is also nice and generic and does the same thing.

Unfortunately for Netscape, their lovely little idea was not included in the XHTML specs, so no valid code for you, loyal Flash users. But the whole rest of your site validates, so why this one annoying bit? Obviously, Your flash embed code also has the <object> tag in there, so perhaps we can just cut the <embed> out and use <object>?

You could do that. It wouldn’t work very well, but you could do it. The problem is that the <object> tag, while valid XHTML, isn’t understood by Netscape-based browsers. Internet Explorer knows what to do with the <object> tag, but what is the point of adhering to standards if your target audience is only IE users?

Is there another, XHTML compliant way to embed Flash content? As a matter of fact, there are two methods that will work. One is known as the Flash Satay method. Flash Satay essentially uses just the <object> tag and works around its limitations by using an empty container movie that then loads the main movie. It’s a decent way of going about things and has its uses. But there is a way that’s even better.

JavaScript to the rescue

Flash Satay is great. It provides us with some standards compliant ways to display Flash movies. But what about detecting the Flash player in the first place? And then there is another issue: search engines. What if we could embed our movie in a standards compliant manner (which search engines seem to favor), detect the player version on the user’s machine, and provide alternate content for search engines and users without Flash all at the same time? Que bueno, yes? Well you can have your banana and eat it too, thanks to Geoff Stearns. Mr. Stearns has written a JavaScript class that replaces an XHTML <div> tag with a Flash movie.

It works like this: We call the JavaScript function, passing our <div> tag as a parameter. The function then parses the XHTML and finds the tag in question. It replaces everything within that tag with the Flash movie we specified in the function call. This allows us to have actual, indexable content in that <div> tag. That means that search engine robots, users without Flash, and users without JavaScript can still see an approximation of the original content.

Stearns’ site contains complete instructions on how to use the JavaScript class, but I’ll walk through it rather quickly.

Publish your Flash .swf file as you normally would. Create your lovely, validly coded XHTML document and its accompanying CSS rules. Copy the file you downloaded called flashobject.js to wherever you keep you JavaScript files (I keep all of my JavaScript files together in a directory on my site named js). In the <head> tags of your HTML document, include the external JavaScript file we downloaded.

 <script type="text/JavaScript"

 src="http://www.wired.com/images/archive/path/to/flashobject.js"></script>



 

Now, figure out where you want to put your Flash movie on the page and add a <div> tag. Something like this, taken from Stearns’ example:

<div id="flashcontent">



Everything in this will be replaced by the Flash content.

Place your alternate content here and users without the Flash plug-in

or with

JavaScript turned off will see this.

Include a link to <a

href="flashobject.html?detectflash=false">bypass the

detection</a> if you wish.



</div>



Now you just need to call the function contained in the flashobject.js file. The code looks like this:

<script type="text/JavaScript">

     // <![CDATA[



     var myMovie = new FlashObject("myMovie.swf", "myMovie", "300",

"300", "7", "#FF6600");

     // if your movie is using flashVars parameters you can still do that

     // using this syntax:

     myMovie.addVariable("flashVarName", "this is passed in via

FlashVars");

     myMovie.write("flashcontent");



     // ]]>



</script>

The biggest and best advantage of this method, at least to my thinking, is its reusability. I use this code extensively on my blog. All my pages are generated from templates, so if I point to the flashobject.js file in my <head> tag template, I automatically have site-wide access to the script. Because my templates are themselves created from smaller chunks of code, I can have two versions of my <head> tag template; one with the code and one without. Whenever I want to add Flash to a page, I just change templates and I can add Flash content without breaking the validator.

Of course, I still have to include a <div> tag and call the function, but that’s the easy part.

And there you have it: a standards compliant way to add Flash to your XHTML.

Introducing sIFR

Now let’s imagine for a moment that you are a purist. You love strict XHTML as only a mother can. Let’s suppose you’re as rabid about your little baby’s standards as Diane Ladd in “Wild at Heart.” How could we convince you that there is a practical application for Flash files, even in your twisted, lipstick-smeared world?

Well, we would criticize your typography of course. We already know your code is impeccable, but wow. Those headlines are still in Georgia huh? Kind of primitive, don’t you think?

As web designers, we have reliable access to maybe six fonts that all users will have. This was one of the limitations of HTML that first drew me to Flash. Now, you may not be as obsessed with typography as some of us (if you know that Mrs Eaves is not Mr. Eaves wife, then you might be obsessed with typography), but wouldn’t you like to use something other than Arial sometimes?

Well, I can’t really help with the body text. But headlines, oh headlines, do I have a revolution for you. It’s called sIFR.

First, a brief history. SIFR is not exactly a new idea, rather an improvement on an old one. Web designers have always disliked the limited selection of fonts available. The problem is that in order for a browser to render a font, that font must reside on the user’s hard drive. How many universally available fonts are there? Well conservatively, probably about six: Verdana, Times, Arial, Helvetica, Courier, and Geneva. Trebuchet, Tahoma and Lucida are also widespread, but less so than the Big Six. If you’re using stylesheets, you know that the only options for total compatibility are simple sans or serif declarations. You declare a sans-serif font for a block of text and it’s the browser’s decision as to which sans-serif font it uses to display the given text.

From a designer’s standpoint, this situation is undesirable to say the least. So, way back when, some folks thought, “Hey, we could replace a headline with a graphic that has the same text, but as an image. That way we can exercise control over the typeface being used. We can use any typeface because it’s an image.”

While a solution, this is still less than ideal. For one thing, it means that every single headline must be generated by hand using some sort of image application. Even if you automate the creation process with scripts, this is impractical for all but the simplest of sites. Today’s database driven, content-assembled-on-the-fly website engineer cannot afford to create a separate image for every single headline.

There is another problem. Actually there are several others, but the biggest one is that this technique effectively ruins the site for the visually impaired. Instead of tags that look like this:

This is my great headline’

You need something like this:

<img scr="mygreatheadline.jpg" alt="This is my great headline">

A screen reader is going to read that whole second line aloud, and the person using it is going to be annoyed because you were too caught up in the appearance of the text to remember that lots of people don’t care about the appearance.

So, allow me to introduce scalable Inman Flash Replacement. Yes, sIFR stands for scalable Inman Flash Replacement. The technique takes its name from the man who invented it, Shaun Inman. The scalable part was added by Mike Davidson, who improved on the original and maintains the current code. The technique is essentially the same as image replacement, but relies on JavaScript and Flash to dynamically replace XHTML text with Flash text.

Why is this better? Many reasons. Foremost, sIFR allows us to code our pages as we normally would. We can create a stylesheet and set the size and other parameters of a headline. With sIFR on the page, something amazing is going to happen. When the browser requests the page, a JavaScript class parses the page for a given variable and replaces it. In our example, we’ll say that the element we want the replace is an <h1> tag, but it could be anything. Wherever the JavaScript finds that <h1> tag, it sets the text contained within the tag to “hidden” and then embeds a Flash movie matching the element’s original size. The script then feeds the Flash movie the hidden text. Finally, like magic, the Flash movie displays the text it gets from the JavaScript.

There are no restrictions for which fonts we can and can’t use within a Flash movie, so we can design our headlines however we’d like.

If the user doesn’t have Flash, doesn’t have JavaScript enabled, doesn’t have either, or is using some assistive device, the original text is still there just as it would have been had we done nothing at all.

How and when to use sIFR

Mike Davidson, who maintains the code for sIFR, has excellent instructions on his site for how to use the code. For the sake of clarity, I’ll walk through a quick example here.

To get started, download the .zip file containing the script. The package also includes the Flash movie template. Open the Flash template and double click on the movieclip that occupies the main stage. This will take you to the actual text box. Just change the font for text box to whatever font you want to use and publish the movie. Upload the resulting .swf file to your site.

Now we need to add sIFR to our XHTML and CSS files to make it work. The first thing to do is include the JavaScript using the <head> tags of XHTML. See our earlier example of the MP3 player for the syntax. Next, open the JavaScript file sifr.js. Near the very bottom of the file, you’ll see a function call that looks like this:


 sIFR.setup();



 

Just below that line, we’re going to add another function call. The syntax is explained in the readme file that accompanied your download. The code I use on my site looks something like this:


 sIFR.replaceElement(named({sSelector:"h1",



 sFlashSrc:"http://www.mysite.com/path/to/sifr.swf", sColor:"#FEDB18",



 sBgColor:"#6f5f45"}));



 

This calls the JavaScript function replaceElement. The sSelector parameter tells the function which tag to replace. The sFlashSrc parameter tells the function where to find the Flash movie. The sColor parameter controls the color of the font and sBgColor controls the background color of the Flash Movie.

In the example above, all the <h1> elements will be replaced. We could get more specific. In fact, you can be as specific or generic as you like with the sSelector parameter. Let’s say for example that we only want to replace <h1> tags that occur in a <div> named body. We would just change our code to read:


 sIFR.replaceElement(named({sSelector:"#body h1",



 sFlashSrc:"http://www.mysite.com/path/to/sifr.swf",



 sColor:"#FEDB18", sBgColor:"#6f5f45"}));



 

There are additional parameters that you can pass to the function to control things like hover states for links, transforming text to uppercase, and more. For a complete list of parameters, see the documentation packaged with your download.

Putting sIFR on the page

The next step is to include the sIFR classes in our CSS file. Open your CSS file in a text editor and add this code:


 .sIFR-hasFlash h1



 {



 visibility: hidden;



 }



 .sIFR-flash { visibility: visible !important; }



 .sIFR-replaced { visibility: visible !important; }



 span.sIFR-alternate



 {



 position: absolute;



 left: 0;



 top: 0;



 width: 0;



 height: 0;



 display: block;



 overflow: hidden;



 letter-spacing: 0;



 }



 

This chunk of CSS does a couple of things. First, it creates a hidden selector class for the element we are going to replace. Then, the rest of the declarations handle the display of the replacement movie.

The primary thing were going to do with this code is use the class .sIFR-hasFlash h1 to control the size of our replacement text. The creators of sIFR refer to this as “tuning” your fonts.

This tuning process can be a little tricky, and is essentially a process of trial and error. The goal is to make the original text the same dimensions as the replacement text. To do so, we can add declarations like line-height, font-size, font-weight and margin or padding to the .sIFR-hasFlash h1 declaration. Unfortunately, there is no general solution I can give you. Some situations require more tuning than others.

If you open up the sifr.js file again and look near the bottom, just above where we inserted our function all earlier. You should see a function that reads:


 sIFR.setup();



 

Comment out that line and add this one just below so you have:


 //sIFR.setup();



 sIFR.debug();



 

This will allow you to see your tuning in real-time. When you’re done, just uncomment the .setup() line and comment out the debug() line.

The only other thing you’ll want to do is change your print-css stylesheet to make sure your replacements don’t happen when the user prints the page. If you’re having problems refer to the sIFR wiki for troubleshooting and more detailed instructions.

There might be a temptation, given this newfound control over fonts, to go a bit crazy and use it everywhere. Resist that temptation. sIFR wasn’t designed to replace everything on the page. Your body text is still going to be limited to the big six. sIFR is best used for headlines, and maybe subheadlines if you don’t have too many.

One thing you may notice is a slight lag time before your headlines are displayed. On my aging G3 iBook, this little pause is about one to two seconds. Presumably, on new equipment it would be even less. If this bothers you, you can set sIFR to show the normal font before it replaces it with Flash.

I should note that you do not have to put the function call in the sifr.js file. In fact, sometimes you may not want to. You can also write it into the XHTML as we did with the earlier script. I think it makes more sense to put it in JavaScript file itself because I use the same headline throughout my site. However, if you wanted to use different fonts on different pages you would need to call the function from each page.

If you ever get stuck using sIFR, refer to the documentation or the wiki. And of course, nothing beats trial and error.

Achieving Perfect Harmony

Well there you have it. Two ways Flash can peacefully co-exist with XHTML in this newfound world of web standards. At the same time, we’ve tackled one of the most persistent issues for all web designers: how to get cool fonts on your site.

If you would like to see both of these techniques in action you can visit my personal site, luxagraf.com. Note that the Flash Object part of my site requires the Flash 8 player.

sIFR is all over the place these days. You can look at the official example page or some bigger sites like ESPN or CBS News. It’s not always easy to tell when either of these techniques are being employed, and that’s kind of the point. If you don’t notice the behind the scenes stuff, then you are witnessing a truly seemless integration of XHTML and Flash.

Adhering to web standards is no longer an excuse to avoid Flash. At the same time, don’t use these techniques to justify doing a whole site in Flash. Flash has its place. It does some things very well and other things are best left to XHTML.

Choose wisely, grasshopper.