Flex Tip 5: Using Runtime CSS
January 24, 2008 – 12:02 pmOn large scale projects that will be deployed on more than just one location it is a constant need for re-skinning the application. This applies mostly to “embedding” projects, that is projects that will need to be integrated (embedded) into an already done site, with a custom template.
First solution would be duplicate the project each time a new theme is required. But this will end up in a bad situation where in one instance a bug is spotted and it will have to be fixed in all of them, making the nightmare of on any programmer.
Second solution adds in scene css, using them as compile-time css. This means that all styles applied to components are stored into an external .css file that is embedded in the application at compile time. But eventually this will be a problem too. On the bug situation mentioned above, using compile time css will end up in compiling the project for each desired theme, one at a time. Not a very good situation either.
And here is where the fun part begins. Using runtime css you will be able to build and deploy the application once and then change the css files on the server each time you need a different skin. This goes without changing anything in the code and when the bug problem appears it’s just a matter of fixing and uploading the app again.
Here is our little example. We will apply a style to a button loaded at runtime. The css looks like this:
1 2 3 4 5 | /* CSS file */ Button { corner-radius: 20; } |
Very simple css file. Note that the class added in the css file is the global Button class used in Flex. This means that we dont need to add a “styleName” property to buttons inside application. Now lets take a look at the main class in the application:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | <?xml version="1.0" encoding="utf-8"?> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" initialize="appInitialize()"> <mx:Script> <![CDATA[ private function appInitialize():void { StyleManager.loadStyleDeclarations( "css/Global.swf" ); } ]]> </mx:Script> <mx:Button x="100" y="100" width="100" height="100" /> </mx:Application> |
We have our button added in the stage (without any mentioning to a style) ready to be skinned by any css loaded at runtime.
The example assumes that you have a Global.css file inside a “css” folder. To be able to load the styles at runtime we need to compile the css into a swf file. The swf file will take all the styles and assets that are required by the css and deliver those to the application. You can compile the css into swf by using the mxmlc compiler shipped with Flex Builder but in Flex Builder 3 this is made seamless. All you need to do is check the Compile CSS to SWF menu item from the menu that appears when right click on Global.css. This assures that when the project will be compiled, the css will be compiled too and stored as .swf in bin-debug and eventually in bin-release folder. Now what remains to do is add the StyleManager.loadStyleDeclarations( "css/Global.swf" ); code in the initialize handler for application, making sure that the .swf with the styles is loaded.
In the example what you should get is a rounded button, telling you that the css is loaded. From now on, you can compile the .css only, adding more styles and when the application runs it will load those.
You can download the example source code from Here.
6 Responses to “Flex Tip 5: Using Runtime CSS”
Hey man!
Awesome tip! I bashed my head a while back, trying to make the runtime skinning work, but at that time it was only possible through some kind of hacks found on the flexcoders mailing list…lost my interest pretty fast :P
Now that’s truly possible…rock on!
cheers!
By Cristian on Jan 25, 2008
I was just researching how to apply styles at runtime and came across this article. Works like a charm. Also, the ability to compile directly from Flex 3 is just one more reason to switch over.
Regards
By sdonaway on Feb 25, 2008
Findong that .loadStyleDeclarations works perfectly well uin Flex 3 bar one issue.
When changing styles at runtime it briefly switches to default style before doing what I want.
Visually this means the movie goes white for 0.5 seconds before applying the new style.
Any ideas on what might be the cause of that ?
By Ted on Mar 15, 2008
Make sure you don’t call StyleManager.unloadStyleDeclarations when switching between styles. That will reset the current style to the default one.
Another thing you can do to avoid this is using the StyleEvent.COMPLETE from StyleManager. Code goes like this:
var styleEvent:IEventDispatcher = StyleManager.loadStyleDeclarations( “yourRootToSWF” );
styleEvent.addEventListener( StyleEvent.COMPLETE, handleStyleLoadComplete );
Now when you call StyleManager.loadStyleDeclarations you can apply a cover to the application with a text like “Loading Styles” and remove it in handleStyleLoadComplete method, when all new styles are loaded.
By Adrian Aioanei on Mar 17, 2008
I have been trying to establish an dynamic load a runtime CSS based skin. I tried to convert my CSS file into a SWF.
However, I get errors after the conversion. They seem to be related to ClassReference.
upSkin: ClassReference(’assets.skins.buttonSkinUp’);
Hoping you can provide some insight as to what’s going on?
By Jason The Saj on Mar 31, 2008
Hey Jason,
I’ve been doing an example with the programmatic skinning and its running ok. What i have different is the skin class in the same package as the css file thus in ClassReference i just add the skin class name like this ClassReference(”CLASS_NAME”).
Here is the example. Hope this helps.
By Adrian Aioanei on Apr 1, 2008