A List Apart


Illustration by Kevin Cornell

Semantic Flash: Slippery When Wet

There’s a belief within the web standards community that Flash is part of a different world. While all approaches have limitations and drawbacks, Flash has been scorned to the point that many refuse to acknowledge its benefits. Ultimately, this has led to the creation of a virtual separation among web designers; those who use Flash use it exclusively (leading to a saturation of full-screen, “Skip Intro”-rich Flash sites on the web) and those who don’t ever give it a second thought.

Article Continues Below

Although the brilliant option of the hybrid (part Flash, part HTML) site had always existed, it’s never really made it far past the typical Flash intro on a corporate homepage. Throughout the history of Flash on the web, the technology has always been intended to be embedded within HTML. Yet it has often seemed a foreign concept to use the two technologies to complement one another.

A not-so-“swft” change

Eventually, a few web designers and developers realized that there were ways to use each technology to its advantage. Over the last several years, there has been a resurgence in the proper use of technology. Debates on semantics abound. JavaScript—and more importantly, unobtrusive DOM scripting—has seen a revival unmatched since the bad old days of DHTML. Most delightfully, Flash is also getting its due. Granted, it’s not as popular as the typical Web 2.Ohwhatsthebigdeal ingredients. Yet.

Slowly but surely, Flash is finding its way into the standardista’s toolkit, and it’s happening in a very exciting way. There’s no need to convince Mr. Web Standards that he should start building full-scale Flash sites. Flash is easily making a new home for itself, not as an alternative, but as a supplement.

sIFR is the perfect example. Shaun Inman, Mike Davidson, and Mark Wubben have done an excellent job in recognizing powerful combinations—semantic content markup with HTML, beautiful font-rendering from Flash, and client-side document transformation with JavaScript—and created a smart and efficient tool for others.

Need more evidence? Take a look at SlideShowPro. Todd Dominey leveraged a task that Flash does well—parsing XML—and created a modular device that is incredibly easy to install and use.

Still a skeptic? Did you know that Flash can detect the presence of a screen reader? Want more? Feel free to check out Flickr, Yahoo! Maps, Google Analytics, or MTV.com. Consider the surface scratched.

Hand in hand

Notice that none of these examples focus on a sole technique. It’s not to say that Flash—or the other methods, for that matter—aren’t useful as standalones, but collaboration can be even more powerful.

Audience participation

Successful integration is obviously possible. So how can you start integrating Flash into your workflow? The first step is to change your mindset. If you can accept that Flash is more than an all-or-nothing deal, half the battle is already won.

Let’s test this theory in the wild. Say you’re working for a nifty Web 2.0 client who rates CDs. You know they subscribe to the stereotypical Ajax-y goodness, so you’ve been kind enough to design as such. You present a set of designs for their “Ratings” page, a part of which looks like this:

  Preview of proposed design

Figure 1. A comp of the proposed website design

You know they’ll be entering content into some sort of CMS, so your goal is to create as automated a process as possible. Taking this to the next step (templating), let’s see this page in action.

Savvy readers will have noticed that there’s something missing in the last file: the reflection. While there might be some contention as to why you’d want to do this in the first place, it’s no secret that the shiny floor technique is stereotypically “Web 2.0.” Let’s just say that the client requested it, and you were accommodating enough to oblige.

Your client is employing your services because they can’t justify the expense of a full-time designer, so it’s your job to make them as self-sustaining as you possibly can. They have access to CD cover artwork, but don’t have the knowledge required to perform image manipulation, not to mention the fact that your previous experience with clients tells you that manual editing usually leads to disaster.

You have three options:

  1. Suggest hiring a full-time graphic designer.
  2. Instruct the client on manually editing files.
  3. Find some way to automate the procedure.

Hiring a dedicated person often works best, but there are times when it’s not as beneficial or not feasible. Unless you have a particularly sharp client, option two should be prohibited. That leaves one more: automation.

The idea behind automation is that a set of standard rules can be applied to many instances. Like Photoshop actions or any batch operation, the biggest obstacle is describing what you would like to accomplish. Once you can verbalize that, the syntax part is easy.

With this example, there should be a way to describe creating a reflection. Essentially, a reflection is a mirror version of an original image, but with a bit more transparency. If only there was a way to manipulate the properties of an image…

Enter Flash. (And its long-lost brother, JavaScript.)

A good foundation should always be the first goal. By using semantic HTML, you can be sure that your content is accessible to all types of users, regardless of which user agent is present or plug-in enabled.

I decided to jump into Flash next because it suits my preferred workflow. Before starting any dynamic tasks, I like to test them out statically. If it works with one hard-coded instance, it shouldn’t be too difficult to get it working with many instances. Without writing any code, I first try and verbalize what I need to do in plain English:

  1. Duplicate the image. I’ll need one copy to be the actual image, and another copy to serve as the reflection.
  2. Rotate the reflection by 180°. Typical reflection logic.
  3. Flip the reflection around the y-axis. Rotating alone won’t cut it. The image has to be flipped in order to pull off the illusion.
  4. Lower the opacity of the reflection. Real world reflections are seldom as strong as the image itself. For the sake of believability, turn the intensity down a notch.
  5. Position the reflection at the correct coordinates, relative to the original image. Because rotation and mirroring alter the registration point of the image, some basic math skills should help to calculate where the reflection should go.

After determining the steps, a quick lookup in the ActionScript dictionary helps to translate words into code. This isn’t a primer on writing ActionScript, so I won’t focus on explaining the code, but for the curious, here’s the magic (one layer, one frame file, all code as frame 1 actions): (Line wraps marked » —Ed.)

Stage.align = "TL";
Stage.scaleMode = "noScale";
Stage.showMenu = false;_root.stop();// ===== cover
_root.createEmptyMovieClip("cover", 1);// local testing
//_root.cover.loadMovie("cover.jpg") _root.cover.loadMovie(_root.jpg);
_root.cover._x = _root.cover._y = 0;// ===== reflection
_root.createEmptyMovieClip("reflection", 2);// local testing
_root.reflection._rotation = 180;
_root.reflection._xscale = -100;
_root.reflection._alpha = 25;
_root.reflection._x = 0;
_root.reflection._y = 277;// ===== mask
_root.attachMovie("mask", "mask", 100);
_root.mask._y = 139;

The example works well with a hard-coded file, but how can we make it work with a number of files? Luckily, all of the content is already accessible within the markup. Using some clever DOM scripting, we can send Flash all the info it needs, and let it do all the grunt work for us. Following the same coding technique, let’s work out what needs to happen to the DOM:

  1. Locate and store references to all of the images on the page. Conveniently, there’s a built-in method for that (document.getElementsByTagName).
  2. Dynamically create Flash files and pass the SWF references to the appropriate images as a variable.
  3. Replace the original images with the newly created Flash files, and insert them into the pages in the correct positions. Small loops and the formidable SWFObject make this happen.

And, for the hungry: (Line wraps marked » —Ed.)

window.onload = function(){   
  if(!document.getElementsByTagName || » 
!document.getElementById) { return; } 
  var covers = document.getElementsByTagName('img'); 
    for(var i = 0; i < covers.length; i++){
      var newflash, newflash_param;  
      newflash_div = document.createElement('div');
      newflash_div.className = 'shiny';  
      covers<i>.parentNode.insertBefore »
(newflash_div, covers<i>);
      var reflections = new SWFObject("covers.swf", »
"mymovie", "138", "211", "7", "#dbd8b7");
      reflections.addVariable('jpg', covers<i> »
    }    while(covers.length > 0){

Have a look at the automated reflection example.

(If you’re brave, here are the source files for experimentation.)

A myriad of possibilities could arise from the marriage of these technologies. I’ve already mentioned a few, and the newest one to hit the stores—pardon the self-promotion—is swfIR. As the technique that directly inspired this article, it uses the same logic to apply a wealth of options to static content.

And there you have it: a few examples and a detailed walkthrough of HTML, Flash, and JavaScript working together to produce a technique that is automated, efficient, beautiful (depending on who you ask) and client-friendly. Though it’s already implied, it’s worth explicitly stating that this is just one sample of the endless possibilities for using Flash in a web standards context. I’ll be discussing additional possibilities in a continuing series on the perks of “Semantic Flash.” Stay tuned!


64 Reader Comments

Load Comments