Robert Bak – Notes

Some programming tips – updated sometimes

Using constants in Flex CSS – with compile time error checking

One of the problems with CSS is that in involves a lot of copy&paste. Having multiple selectors which share a common property value (like a font color) is common, but in CSS you still need to have an individual color for each selector. So you end up with code that looks like this:

s|TextArea{
    color:#eeeeee;  
}

s|Button{
    color:#eeeeee; /* the same color as above*/
}

Which is ok, but involves a lot of searching and replacing and careful analysis of the changes being made. I’ve been thinking about a way to put constants in there for a while and finally found a nice one today, while reading documentation for Flex 4.5. It’s really simple to use and has an added bonus – the compiler will make sure that the consts are actually defined, which should help with maintainability.

Defining the constants

Let’s start by defining the constants and their value. You need to create a new actionscript file (in my case style\StyleConstants.as), than throw away all the code that’s inside (eg. the package and class definitions), and define a const inside, we’ll use the file later.

/* file: style\StyleConstants.as */
private const someColorConstant:uint = 0xff0000;

Please notice that the variable can be private and will still work (it can also be public).

Putting Actionscript variables in CSS – PropertyReference

Looking at the Flex CSS documentation I’ve found that there’s a new keyword that you can use in Flex 4 CSS – PropertyReference. Since the docs say that “You can use document properties in your CSS” we’re going to do just that. The CSS class will be the modification of the one at the top, I’ll put it in style\Style.css and replace the colors with a pointer to the const declared above.

/* file: style\Style.css */
@namespace s "library://ns.adobe.com/flex/spark";
@namespace mx "library://ns.adobe.com/flex/mx";

s|TextArea{
    color:PropertyReference("someColorConstant");
}

s|Button{
    color:PropertyReference("someColorConstant");
}

Getting it all together

The last thing left to do is creating the application that will use the style, it’s also very basic.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
               xmlns:s="library://ns.adobe.com/flex/spark" >
   
    <!-- // STYLE -->
    <fx:Style source="style/style.css" />
    <fx:Script>
        <![CDATA[
            include "style/StyleConstants.as";
        ]]>
    </fx:Script>
    <!-- // STYLE END -->
       
    <s:Button x="10" y="10" label="Some button"/>
    <s:TextArea x="100" y="10" text="Some text"/>
   
</s:Application>

As you can see, inside the main Application file, we import the css the regular way, the only addition is the include in line 9, which puts all the constants defined inside the StyleConstants.as inside the Application, allowing the PropertyReference to find them. Once you run this app you should see a great UI looking like this:

Which does exactly what it should – uses the same color for both the Button and TextArea.

Compile time checking?

Yup. If you mess up you’re going to get a message from the compiler himself.

// change the css to:
s|Button{
    color:PropertyReference("someColorConstantWithAWrongName");
}

Will get you:

Which is really nice.

Notes

A few things to keep in mind:
1) This will not work with Flex 3.
2) You need to put the links to the CSS and consts in the main application file.
3) You can use a var instead of a const when defining the values. This will allow you to change the style during runtime, but keep in mind that this will not update the styles of the components that were already created but only the newly created ones.
So the code below

/* Change the file: style\StyleConstants.as to */
private var someColorConstant:uint = 0xff0000;

/** add a click handler in the main application **/
protected function buttonClick(event:MouseEvent):void
            {
                this.someColorConstant = 0x0000ff;
                var newButton:Button = new Button();
                newButton.label = "New button";
                this.addElement(newButton);
            }

Will get you this:

4) This allows you to set more than just simple values, allowing you to get back a functionality described at Flex Examples (Changing the opening and closing easing functions …) using the code below.

// file style\StyleConstants.as
import mx.effects.easing.Bounce;

private var definedOpenEasing:Function  = mx.effects.easing.Bounce.easeOut;
private var definedCloseEasing:Function  = mx.effects.easing.Bounce.easeIn;

// file style\Style.css
mx|ComboBox {
    openDuration: 1000;
    openEasingFunction: PropertyReference("definedOpenEasing");
    closeDuration: 1000;
    closeEasingFunction: PropertyReference("definedCloseEasing");
    alternatingItemColors: #DFDFDF, #EEEEEE;
}

5) For other ways that create similar results, check stackoverflow.com

Download source code.

2 thoughts on “Using constants in Flex CSS – with compile time error checking

Leave a Reply

Your email address will not be published. Required fields are marked *