Posted by Sandro on October 1st, 2009

Embedding Cascading Style Sheets in Flash/Flex

It’s nice to be able to quickly adapt to clients wishes, when they come to you and ask for this text to be bigger or for that link to be bold when you hover over it. Simply replace the css file and your set.

But sometimes you don’t want to go through the process of adding a Loader and EventListeners so you can load that external css file just for a bit of fancy html text. Sometimes it would be nice to just compile that thing into your swf and pretty much be done with it.

Well lucky enough we can embed files in classes with the embed tag.

Example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// Embed your stylesheet with the octet-stream mime-type
[Embed(source="assets/stylesheet.css", mimeType="application/octet-stream")]
private var stylesCSS:Class;
 
public function createStyleSheetObject():StyleSheet
{
    // create a new StyleSheet instance
    var styleSheet:StyleSheet = new StyleSheet();
    // create a instance of the styles as ByteArray
    var byteArray:ByteArray = new stylesCSS() as ByteArray;
    // read the content
    var stylesString:String = byteArray.readUTFBytes(byteArray.length);
    // parse the string by the stylesheet and done!
    styleSheet.parseCSS(stylesString);
    return styleSheet;
}

Of course this would be the proper way, if you want to save some lines you could also do the following:

1
2
3
4
5
6
7
8
9
10
11
// Embed your stylesheet with the octet-stream mime-type
[Embed(source="assets/stylesheet.css", mimeType="application/octet-stream")]
private var stylesCSS:Class;
 
public function createStyleSheetObject():StyleSheet
{
    // create a new StyleSheet instance
    var styleSheet:StyleSheet = new StyleSheet();
    styleSheet.parseCSS(new stylesCSS().toString());
    return styleSheet;
}

There you go, your StyleSheet is ready to be used.

UPDATE:

Vikas had a very good question concering how to embed multiple stylesheets with this method. I figured i would give another example on how to achieve this very simply. In order to not have to deal with multiple files to embed, you could just join all the styles for a stylesheet into one file, like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/* StyleSheet 1 */
 
.myStyle
{
	fontFamily: Arial;
	fontWeight: bold;
}
/* @eos */
 
/* StyleSheet 2 */
 
.myStyle
{
	fontFamily: Georgia;
	fontWeight: normal;
}
/* @eos */

As you see there is a comment block called /* @eos */ that represent the “end of stylesheet”. This we will split in our code as follows:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
// Embed your stylesheet with the octet-stream mime-type
[Embed(source="assets/stylesheet.css", mimeType="application/octet-stream")]
private var stylesCSS:Class;
 
public function createStyleSheets():Array
{
    // create a instance of the styles as ByteArray
    var byteArray:ByteArray = new stylesCSS() as ByteArray;
 
    // read the content
    var stylesString:String = byteArray.readUTFBytes(byteArray.length);
 
    // split the string with your delimiter. in this case "/* @eos */"
    var matches:Array = stylesString.split("/* @eos */");
 
    // loop through the generated array and create the stylesheets and push
    // them to a new array that will contain those stylesheet objects
    var styleSheets:Array = [];
    var n:int = matches.length;
    for (var i:int = 0; i < n; i++)
    {
        var styleSheet:StyleSheet = new StyleSheet();
        styleSheet.parseCSS(matches[i]);
        styleSheets.push(styleSheet);
    }
 
    // return the StyleSheet Array
    return styleSheets;
}

And voila, you got an array of stylesheets that you can apply to wherever you want. Hope that helps!

Related Posts
Post a Comment


13 Comments »

  1. Yeah, that is a really cool advice! Thx!

    comment-bottom
  2. Interesting things,
    p.s. subscribed to your blog.

    comment-bottom
  3. Vicky says:

    Hi,

    Thanks for the example. I have few doubts though, where do we call this function “createStyleSheetObject” ?? And, how can we embed multiple CSS in the application. I want to change the stylesheet effect at runtime but want to embed all the stylesheets. Please suggest.

    Thanks for your time and the example.

    Take Care,
    Vikas

    comment-bottom
  4. Sandro says:

    Hi Vikas

    The Function/Method is just an example method. You could just execute the same code from within your init method or the first method you call when you instantiate the class that embeds the stylesheet. That part is entirely up to you.

    Concerning your question about how to implement multiple stylesheets: i updated the blog post to include an example of how i think would probably be the easiest approach to do that.

    Hope that helps you,
    Sandro

    comment-bottom
  5. I am assuming but this will only work when you set the styleSheet of a textInput / textArea. This will not work on any Flex class. right?

    comment-bottom
  6. Sandro says:

    Actually you can apply those stylesheets on Flex Text Objects. It requires a little trick though. Check out: http://www.flexfreaks.com/forums/viewtopic.php?id=6

    comment-bottom
  7. Games Up says:

    Thats exactly what I was looking for! Thanks a bunch mate. :-)

    comment-bottom
  8. Hi Sandro

    This is great and love it that you have answered Vikas question. This will be very useful. Cheers

    comment-bottom
  9. Rodislav says:

    Hi, nice idea, what about memory/cpu usage !?

    comment-bottom
  10. Rodislav says:

    And one thing :) is that cross platform !? because i met errors while working with utf bytes in *nix systems, where everything goes utf-8 by default.

    comment-bottom
  11. Rodislav says:

    @Vickas

    private var allStyles:Object = {}

    public function getStyle(style_:Class):StyleSheet
    {
    var className:String = String(style_)

    if(allStyles.hasOwnProperty(className) == false)
    {
    var styleSheet:StyleSheet = new StyleSheet();
    styleSheet.parseCSS(new style_().toString());
    allStyles[className] = styleSheet
    }

    return allStyles[className]
    }

    // then call this function

    myTextField.styleSheet = getStyle(stylesCSS)

    // if you want this more generic, then embed css in this way
    // make everything static, and public
    // class declaration …
    ..CSSManager {
    [Embed(source=”assets/stylesheet.css”, mimeType=”application/octet-stream”)]
    public static var stylesCSS:Class;

    public static function getStyle(…

    // …end class declaration
    }

    // then use it

    myTextField.styleSheet = CSSManager.getStyle(CSSManager.stylesCSS)

    comment-bottom
  12. Prabhu says:

    Hi,

    I am trying to include dynamic style sheet for my flex application. Till now i am not getting any solution. I am using Flex 4 version.

    This is my sample css file.

    /* CSS file */
    @namespace s “library://ns.adobe.com/flex/spark”;
    @namespace mx “library://ns.adobe.com/flex/mx”;

    mx|Label.clsLabel {
    fontSize: 20;
    color: #7F4818;
    }

    My MXML file
    ============

    I have tried the above createStyleSheetObject() function in the application. This function reads the css content and parse it then return the proper style sheet object.

    But the style is not applying for this Label text. Please help me to solve this problem.

    Thanks,

    Prabhu

    comment-bottom
  13. Prabhu says:

    This is my label.

    And, Please tell me how to apply the style sheet to GLOBAL application not for the particular text or label.

    Hope anybody will help me…

    Thanks,

    Prabhu

    comment-bottom

RSS feed for comments on this post | TrackBack URL

Leave a comment

Flash Flex Actionscript Tutorials Tutorial AS2 AS3 AS1 Feeds MXML Blog Zinc AIR Launcher Twitter Tweetr Yet Another Coverflow Liip Adobe Macromedia PHP MySQL PostgreSQL XML AMF MXNA Phidgets Schweiz Switzerland Suisse Svizzera Fribourg Freiburg Aargau Baden Publicis Accessibility JAcc Qt FOSDR Flash on the Beach Forum Conference Speaker Speaking Talk