Hack 91 CSS-Based Browser Centering

figs/beginner.gif figs/hack91.gif

Centering an unscaled Flash SWF can inadvertently expose off-stage content. Center a Flash SWF using XHTML and CSS for excellent results without displaying off-stage content and in a standards-compliant way.

One of the most common initial problems a new designer faces is centering the SWF in the browser [Hack #90] . Although there are several ways to do this, all have at least some issues. This hack shows the options and the hacks needed to get them working better.

Centering Using the Publish Settings

Consider the SWF shown in Figure 11-9.

Figure 11-9. A center calibration pattern
figs/flhk_1109.gif


The central calibration pattern (a.k.a. test card) covers the Stage, and the four outer shapes (the two circle-squares and two squares) are outside the Stage area. The light gray frame is also outside the Stage area.

If you allow the Stage to scale to fit the browser window (using FilePublish SettingsHTML, then set the Dimensions to percent), you won't see the four outer shapes.

The problem with scaling a SWF in the browser is that, if the user opens a large browser window, the large size of the resulting SWF can dramatically reduce performance of the site. Setting the Horizontal and Vertical options under Flash Alignment to Center and setting the Scale option to No Scale, as shown in Figure 11-8 (in the preceding hack), gives you the centering shown in Figure 11-10.

Figure 11-10. A centered, unscaled calibration pattern
figs/flhk_1110.gif


The SWF is now centered, but you also see all the off-stage content. This is fine for some sites, but many sites have content hidden off stage or partially off stage. It is normal to want to hide content that is currently off stage when creating animation in Flash because this allows panning shots and zoom shots.

For example, consider the SWF in Figure 11-11. This is an animation in progress by Adam Philips, a sometime collaborator of mine.

Figure 11-11. A SWF unintentionally showing off-stage content
figs/flhk_1111.gif


So, although we can center a SWF in the browser window via the Publish Settings alone, it has a significant disadvantage in that off-stage content is also visible.

Our goal is to hide all off-stage content. As you can see from the shot of the same frame in the final animation, shown in Figure 11-12, only the on-stage content is visible. We can achieve this effect via a little HTML hand-coding.

Figure 11-12. The final SWF, hiding off-stage content
figs/flhk_1112.gif


Centering Using HTML

The way to center a SWF in Flash Player 6 and earlier is simple?use an HTML table. Flash MX produces HTML code that uses the <object> and <embed> tags to embed the SWF in the web page. All you have to do is enclose these two tags with a simple <table> tag with horizontal (align="center") and vertical (valign="middle") attributes, as follows (hand-coded additions are shown in bold):

<html>

<head>

<title>myTitle</title>

</head>

<body bgcolor="#FFFFFF">

<!--URLs used in the movie-->

<!--text used in the movie-->

<table width="100%" height="100%" border="0">

<tr align="center" valign="middle">

<td>

<object... 



...</object>

</td>

</tr>

</table>

</body>

</html>

This change not only centers your SWF, it also hides the off-stage content. The trouble is that this method doesn't work for Flash MX 2004. Flash MX 2004 exports XHTML, not HTML, and HTML table vertical centering does not work well in XHTML. Regardless of the fact that we could fix the problem by embedding our Flash 7 files in HTML, we should really be embracing XHTML and using CSS <div> and <span> tags instead of deprecated <table> tags and alignment attributes.

Centering a Flash MX 2004 SWF Using CSS

Because Flash MX 2004 exports XHTML, the valign attribute is a no-no, and, although tables are supported, it is better to perform all our formatting in CSS.

The trouble with CSS is that there is no direct way to center anything vertically?we have to hack it.

Ignoring the detailed <object>, <embed>, and <param> tag attributes, a typical Flash MX 2004 XHTML file looks something like this:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 

"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">

<head>

<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />

<title>myFlash</title>

</head>

<body bgcolor="#999999">

<!--URLs used in the movie-->

<!--text used in the movie-->

<object...



...</object>

</body>

</html>

To center our Flash content, we first need to hand-edit the XHTML to add a style definition.

To quickly edit the XHTML associated with a Flash SWF that is being viewed locally on IE, select ViewSource. Of course, this depends on your file associations opening a plain-text editor such as Notepad and not Word!

Add the following style definition between the <head> and <\head> tags:

<style type="text/css"> 

<!--

body 

{

 margin: 0px

}

#centercontent

{

 text-align: center;

 position: absolute;

 top: 50%;

 left: 50%;

}

-->

</style>

This should theoretically place your SWF 50% from the lefthand and top edges of the browser (as well as getting rid of any gutters around the edge of the page), but wouldn't you know it, CSS takes the registration point of the SWF to be its top-left corner. You can see this misalignment if you enclose the <object> and <embed> tags with a <div> tag using the centercontent attribute, as follows (additions are shown in bold):

<div id="centercontent">

<object ...



...</object>

</div>

CSS has centered the SWF, but it's the top-left corner of the SWF that is centered, as shown in Figure 11-13.

Figure 11-13. The SWF's upper-left corner is in the center of the browser window
figs/flhk_1113.gif


Employing the little-known fact that CSS allows negative margins, we can have our cake and eat it too. If we offset the left and top margins by an amount equal to half the height and width of the SWF's Stage, we also offset the SWF in such a way that the center point of the SWF and browser coincide, as shown in Figure 11-14.

Figure 11-14. Centering the SWF with negative margins in CSS
figs/flhk_1114.gif


Add the following to the #centercontent CSS definition in the XHTML file, assuming a default Flash Stage size (550 400 pixels):

#centercontent

{

 margin-left: -275px;

 margin-top: -200px;

 text-align: center;

 position: absolute;

 top: 50%;

 left: 50%;

}

The margin-left and margin-top attributes are set equal to minus half the width and height of your Flash Stage, in pixels. This technique centers your SWF in any browser that understands XHTML and CSS (and XHTML and CSS go together like, um, two things that are pretty much useless without each other).

The final result, in which the SWF is centered and unscaled without revealing off-stage content, is shown in Figure 11-15.

Figure 11-15. The SWF is centered and unscaled without showing off-stage content
figs/flhk_1115.gif


Final Thoughts

As Flash designers, we should not stick to the old ways when it comes to HTML versus XHTML/CSS. Although properly centering a SWF using only CSS is not obvious, it's not a problem now that you know one or two hacks to make the browser behave.