Hack 46 HTML and CSS in Flash

figs/moderate.gif figs/hack46.gif

Flash MX 2004 offers increased HTML formatting support and adds CSS support. Use them together to create pages that look like Flash but load like traditional HTML pages.

Text in Flash can be formatted in numerous ways, such as using an instance of the TextFormat class to apply formatting to a TextField instance [Hack #42] . For those who prefer using HTML formatting tags, Flash MX and later support basic HTML formatting. Flash MX 2004 adds support for CSS formatting, which makes it easy to apply and change text styles across an entire Flash presentation.

Formatting text in Flash the way you can in HTML, however, doesn't make Flash behave entirely like HTML in a browser. One of the biggest problems with Flash sites is that you can't always see them load in the same way a simple HTML page does. An HTML page displays most of its assets as soon as they load, so you can see the page building up. There is no need for a preloader or any streaming or other bandwidth management.

Flash sites may be better than HTML for animation and interactivity, but the counterintuitive way that Flash sites tend to load is disconcerting to many users. In particular:

  • Users cannot decide, within a second or two, whether a page is what they are looking for by scanning the first few loaded assets, as they can with a loading HTML web page.

  • Flash content doesn't normally load in order of bandwidth weight. For example, most HTML web pages display text and empty tables almost immediately, then the images appear, and finally embedded media elements such as video appear. In Flash, if there is a 150 KB download for frame 1 of the timeline, followed by 3 KB of simple text on frame 2, you will not see that 3 KB of text until after the initial 150 KB loads.

Although both of these issues can be fixed by good Flash design, Flash MX 2004's HTML formatting support allows you to load a number of assets directly into text fields in the same way traditional HTML loads into the browser.

Formatting Text with HTML

Text fields typically render text literally. So, if you want to display verbatim text, you can use the TextField.text property. In this example, the HTML tags are ignored for formatting purposes and rendered as literal text:

myText.text = "Enter any <b>HTML formatted</b> text here";

trace(myText.text);

// Displays:

Enter any <b>HTML formatted</b> text here

However, to tell Flash to render the contents of a text field as HTML, set the html property to true and assign the HTML text to the htmlText property, as follows (note the bolded output):

myText.html = true;

myText.htmlText = "Enter any <b>HTML formatted</b> text here";

trace(myText.text);

// Displays:

Enter any HTML formatted text here

The string you equate to myText.htmlText can have any of the following HTML formatting tags within it: <a> (with attributes href and target), <b>, <br>, <font> (with attributes face, color, and size), <i>, <li>, <p>, <span>, and <u>.

The class attribute is also supported, allowing you to make CSS class definitions, and you can also make CSS style definitions, as we shall see in a moment.

There are a couple of differences between the Flash and HTML implementation of some of these tags.

First, if you surround a block of text with <a> and </a> (the hyperlink or anchor tag) in Flash, it will not change text style to imply a link (it doesn't automatically create underlined blue text). You have to set the formatting explicitly with other tags. For example, to make a link appear with underlining, use the <u> tag:

myText.html = true;

myText.htmlText = "This is a <u><a href = 'somelink'>link<\a><\u>";

This yields the text shown in Figure 6-17, with the word "link" acting as a link.

Figure 6-17. Flash text using the anchor and underline tags together to create an HTML link
figs/flhk_0617.gif


However, there is a better way to create HTML-like formatting using Flash MX 2004's support for CSS.

Formatting with CSS

Cascading Style Sheets (CSS) allow you to specify formatting using a stylesheet (stored either internally or externally in a .css file). Changing the stylesheet makes it easy to change the text styles throughout your entire presentation. Flash MX 2004 supports the HTML class attribute to define stylesheets, allowing you to add CSS formatting to your text. For example, you can define a stylesheet with a text style that makes hyperlinks blue [Hack #93] . You should also note that, when using external text files to define your CSS, you need to make sure that your CSS is fully loaded before using it, something browsers handle for you when loading stylesheets for HTML pages. The following code snippet correctly loads an external stylesheet named myExternalCSS.css and uses it to format some HTML text within a Flash text field:

// Define a new StyleSheet object

var myStyle = new TextField.StyleSheet( );

// When the stylesheet loads, use it to format the text

myStyle.onLoad = function( ) {

  myText.styleSheet = this;

  myText.html = true;

  myText.htmlText = myHTML;

};

myStyle.load("myExternalCSS.css");

myHTML = "<p class = 'title'>Creating an efficient walk cycle</p>"

myHTML+= "<br><p><span class = 'emphasis'>Scribble</span> moves very " +

   "quickly in the final work, far too quickly for the viewer to see " + 

   "the lack of frames. He also spends a lot of time in the air, thus " +

   "minimizing the slide walk effect.</p>"

myHTML+= "<p>You can see an example of him moving <a href = " + 

   "'someURL'>here</a>.<br><br>"

myHTML+= "<p>Of course, when two designers get together, easy options " +

   "always go out of the window...(etc).</p>"

The CSS file, myExternalCSS.css, is a simple text file defining our CSS classes and styles:

body {  

  font-family: Verdana, Arial, Helvetica, sans-serif;  

  font-size: 12px;  

  font-weight: normal;

  text-decoration: none; 

  color:#909090;

}

.emphasis {

  font-family: Verdana, Arial, Helvetica, sans-serif;

  font-size: 12px; 

  font-weight: normal; 

  text-decoration: none; 

  color:#404080;

}

.title {

  font-family: Verdana, Arial, Helvetica, sans-serif;

  font-size: 16px; 

  font-weight: bold; 

  text-decoration: none; 

  color:#8080A0;

}

a:link {

  font-family: Verdana, Arial, Helvetica, sans-serif;

  font-size: 10px; 

  font-weight: none; 

  text-decoration: underline; 

  color:#8080A0;

}

a:visited {

  font-family: Verdana, Arial, Helvetica, sans-serif;

  font-size: 10px; 

  font-weight: bold; 

  text-decoration: underline; 

  color:#333355;

}

a:active {

  font-family: Verdana, Arial, Helvetica, sans-serif;

  font-size: 10px; 

  font-weight: bold; 

  text-decoration: underline; 

  color:#444444;

}

a:hover {

  font-family: Verdana, Arial, Helvetica, sans-serif;

  font-size: 10px; 

  font-weight: bold; 

  text-decoration: underline; 

  color:#C08080;

}

There are a few things to notice here:

  • Although Flash doesn't support HTML heading tags, such as <h1> and <h2>, we can overcome this limitation by defining our own CSS classes, such as .title in the preceding example.

  • Flash treats the font measurements px (pixel) and pt (point) as the same thing. So it makes no difference which one you use in your stylesheet.

  • Flash's CSS support allows you to define HTML links properly. The text representing the link will change between the link, visited, active, and hover states, as specified by our stylesheet.

  • The color properties must be literal numbers, such as #444444. You cannot use color names commonly supported by browsers.

  • Just as you can define the CSS file externally, you can define your HTML in a separate text file and load it via LoadVars.load( ). However, if you do load external HTML, make sure each text file is loaded before loading the next one: first load the CSS file, then load the HTML text file, then put the text data into the text field. Otherwise, the CSS definitions will not be defined, or the HTML text may not be loaded when you place it into the text field.

If your HTML text is relatively short, define it within the SWF so that it is compressed. However, images within your HTML can be loaded at runtime using the <img> tag as discussed shortly.


Figure 6-18 shows the results of using the preceding code and CSS file, assuming the Stage contains a dynamic text field named myText.

Figure 6-18. CSS formatted text in Flash
figs/flhk_0618.gif


Embedding Images

The real beauty of Flash MX 2004's HTML support is using the <img> tag's src attribute to embed a JPEG image in a text field. For example, the following changes (shown in bold) to the preceding code specify an image within one of our <p> tags:

myHTML = "<p class = 'title'>Creating an efficient walk cycle</p>"

myHTML+= "<br><p><img src = 'walk.jpg' align = 'right'> " +

   "<span class = 'emphasis'>Scribble</span> moves very " +

   "quickly in the final work, far too quickly for the viewer to see " +

   "the lack of frames. He also spends a lot of time in the air, thus " +

   "minimizing the slide walk effect.</p>"

myHTML+= "<p>You can see an example of him moving <a href = 'someURL'>here</

a>.<br><br><br><br>"

myHTML+= "<p>Of course, when two designers get together, easy options always go out 

of the window...(etc)</p>."

The preceding code yields the results shown in Figure 6-19.

Figure 6-19. CSS-formatted HTML text, complete with embedded image, loaded at runtime
figs/flhk_0619.gif


When the HTML text is parsed at runtime, the image is loaded. You will see the text appear first. Then, once the image has loaded, it too will appear, and the text will wrap to accommodate it. Just like browser-rendered HTML!

Note that the <p> and <img> tags can be a little nonstandard in their operation:

  • The <p></p> blocks do not add whitespace between each other, so you have to resort to <br> tags, as per the preceding listing.

  • The <img> tag can be temperamental and will not work if it is the only tag in a text field. You should place some HTML tags on either side of the <img> to fix this (usually paragraphs with a single blank space or a couple of <br> tags do the trick). Exactly which tags are required seems to vary and may be related to the size of the text field.

  • Flash cannot load progressive JPEG images via <img>. If you use a progressive JPEG, the image will not appear.

  • The <img> tag is supported only in dynamic and input text fields whose TextField.multiline and TextField.wordwrap are set to true.

  • To embed a SWF, set the <img> tag's src attribute to the path of a SWF file. To embed a movie clip, set the src attribute to the linkage identifier of a movie clip symbol.

  • Use the <img> tag's optional id attribute to specify a name that can be used to control the embedded content via ActionScript.

Final Thoughts

Flash MX 2004 includes much greater control of text via subsets of standard HTML and CSS definitions. To keep the Flash Player small, Macromedia has not provided a full implementation, and there are some differences from browser-based CSS. The subset of supported tags and CSS definitions has been carefully chosen. Tags such as headings are not supported, but you can easily define your own custom CSS classes or styles to take their place.

Although a number of designers have complained about the lack of support for any HTML-based tables or advanced CSS block and margin formatting, the HTML/CSS support allows you to quickly and easily load and position large amounts of text and images at runtime, something that was previously problematic.

More importantly, Flash MX 2004's support of CSS and HTML allows you to better separate your text and image content from the Flash site user interface (and even keep it separate from the SWF file), something that can make your content much more flexible for offline and online updates.