Tutorial details:
Written by: Jed Wood (usableFlash.com)
Time: About 15 minutes
Difficulty Level: Intermediate
Requirements: Flash MX
Topics Covered: Stage Object, handling resize, HTML embed code.
Assumed knowledge: Familiar with Variables, Objects, Methods, Flash MX Event Model, Listeners

Sample SWF.

Introduction:
Because I only really got into Actionscripting just before MX was released, I get surprised by how often the newer features go unused by many "long-time" Flash developers. One of those is handling a resizable stage area (aka a "strechy" layout, as opposed to fixed sizes and positions). Many graphic designers prefer fixed size, and for some things that's fine. But let's not forget that many people out there still have 800 x 600 monitors, while many others have spent serious cash on huge high-res displays. If you really want your Flash applications to be "well-behaved" on the web, and let big screens use their expensive space while not making life a pain for the little screens, you'll want to make sure you have a grasp on these concepts. We're going to cover two general issues.

  1. Writing the Actionscript to change the size and position of elements based on window size
  2. Setting the HTML that embeds our Flash movies to allow us the proper control

Setting the Stage:
Open Flash MX and grab the source FLA so you don't have to waste time drawing dummy elements.
We're going to start with the STAGE object, and set two properties:

// set the Flash movie to have a fixed anchor in the top left corner of? the screen.
Stage.align = "LT";
// prevent the Flash movie from resizing when the browser window changes size.
Stage.scaleMode = "noScale";

Simple enough. Basically, we're just setting some parameters here that can also be handled by HTML. However, the Actionscript will always overide what is set in the HTML, which will be important later. Also, I find these two lines handy for displaying an .swf in the browser directly without embedding it in HTML.

"Listening" for the resize:
With the Flash movie as a whole anchored and not scaling, we're ready to listen for when the stage is resized so we can tell certain elements to move or change size. If you need more details on Listeners in Flash MX, read through Guy Watson's tutorial, linked in Related Articles below.

// create a listener object
stageListener = new Object();
// add a methods for it to do certain things when the Stage is resized by our user
stageListener.onResize = function() {
        stretchHeader();
        expandBodyText();
}

What I've done here is created two custom functions that will be called when the stage is resized. You can add whatever you want. Finally, we have to add our new Object to the list of "listeners" for the Stage:

// add new object to Stage listeners
Stage.addListener(stageListener);

Now we'll define each of those functions:

expandTop = function() {
        // expand the top banner/header/masthead - whatever you want to
        //call it - to be as wide as the stage
        bannerBackground_mc._width = Stage.width;
        // then move our nice little "contact us" button
        //so it stays right-aligned with the page
        contactUs_mc._x? = Stage.width - contactUs_mc._width - 10;
}

Two things to note here: 1- The "._width" vs ".width" can be confusing. Just remember that all MCs and TextFields will use _width, and _height, whereas the Stage uses .width and .height. 2 - Notice how I didn't just set the Contact Us mc to be "Stage.width - whatever." If your projects are anything like mine, you can almost be certain that sometime down the road, the width of that button is going to change. By planning ahead for it, we won't have to pick through our actionscript and change things.

expandBodyText = function() {
        body_txt._height = Stage.height - body_txt._y - 10;
        myScrollBar.setSize(Stage.height - myScrollBar._y - 10);
}

Once again, notice that the only hard coded number I have is the bottom margin (which of course could also be pulled from a global variable). Now if I end up bumping the text field and its scrollBar down 20 pixels to make room for our new banner ads, I won't have to change the actionscript.

And there you have it. ScrollPanes, TextFields, Buttons- whatever. You can move them all, expand them, shrink them, and keep certain elements just how they are.

Before they actually resize:
So this will all work great once they user resizes the window. But notice in the little example we have that it doesn't adjust when the page first loads? I've intentionally left out just one line of code that you can add yourself. All we do is tell our listener object that the stage has been resized, even though it really hasn't. Simply call the function:

stageListener.onResize();

Simple but vital- HTML Embed Code:
Just go to Publish Settings, select the HTML tab and set your movie size to percent: 100% by 100%. Huh? But I thought we wrote the actionscript to prevent scaling? Exactly. See, the browser will think "this movie is scaling, so I won't show any scrollBars if it gets too small in one direction or another," but the actionscript is keeping our movie the right size.

Mix and Match- Fixed in one direction, Flexible the other:
One of the usability drawbacks of all-Flash content is that the scrollBars don't respond to Mouse Scroll Wheels. I know there are funky code bits out there that make it work in certain browsers, and I believe MX 2004 has addressed this issue (?). But what if I have a nice long Flash web page or application, and I want it to look and behave like a good ol' HTML/CSS page that has flexible width but a more fixed height? And I want a regular browser scrollBar to appear? or what if my new killer app simply demands a width of 1000 pixels, but can be any height, and I want people to see the horizontal scrollBar on their browser so they know they're missing something if they're window is too skinny (which is exactly what happens with my webSort app)? Well, that's just as easy to fix. Take a look at the HTML code in your published page, and you'll see two paramters for width and height (one in the PARAM NAME section, and one in the EMBED section). All you have to do is change the "100%" for the width to a fixed number like "1000", and keep the height paramters at 100%. You can't do this from within Flash- it's gotta be straight in the HTML.

Well, I hope that gets you started. We didn't even talk about using percentages of the Stage width for HTML type of columns, or making arrays to hold all similarly aligned objects that all move with one function that loops through the array. There's lots of great stuff you can do. Take the few extra minutes and do it, and lets stop making fixed width chrome-less pop-up windows for all our Flash stuff, okay?

Please feel free to drop me a note if you have any questions, suggestions, or examples of Flash sites that make great use of these dynamic layout capabilities.