CSS Positioning with Flex 2
Among the countless new features offered by Flex 2 is constraints-based layout. If you haven’t had a chance to explore the use of constraints I encourage you to spend some time with the approach. I was a skeptic at first myself, but have since come to really enjoy the lightweight results (as compared to flow-based layout which generally involves deep nesting of boxes to achieve complex layouts). At the core of constraints-based layout is a series of properties that allow you to specify positioning and anchoring of your controls and containers.
To be clear, flow-based layout and constraints-based layout aren’t mutually exclusive. Combining the two for their strengths lends itself to rapid development using Flex Builder’s design view.
I was curious about these constraints properties, so one day I looked them up in the language reference. What I found is that they weren’t properties at all! The constraints I had been putting inline were actually styles. This meant that I could externalize them and leverage an external CSS to control the appearance of my user interface. Take the following code and screenshot as a starting point.
<mx:Application layout=”absolute” xmlns:mx=”http://www.adobe.com/2006/mxml”>
<mx:Panel
x=”10″
y=”10″
width=”274″
height=”148″
layout=”absolute”
title=”Login”>
<mx:Label x=”10″ y=”12″ text=”Username:” />
<mx:TextInput x=”85″ y=”10″ />
<mx:Label x=”10″ y=”42″ text=”Password:” />
<mx:TextInput x=”85″ y=”40″ displayAsPassword=”true” />
<mx:ControlBar>
<mx:Button label=”Login” />
</mx:ControlBar>
</mx:Panel>
</mx:Application>

At first pass, when you look at the screen and code nothing seems obviously wrong or lacking. When you take a closer look however, you start to see some shortcomings of how this UI has been put together. You might notice for example, that the login dialog is always going to be at the upper-left of the application. We’d probably like that to be centered in the application based on screen resolution.
The login dialog has also been made specifically to fit the size of the TextInput controls. There’s no width information on the TextInput controls, so they will default to 150 pixels. What would happen if I needed to add another field to the login and the preceding label was longer than the existing username and password labels?
This would force me to put the TextInput further to the right. To maintain alignment, I’d then have to revisit the other TextInput controls and align them further to the right as well. All this pushing to the right would mean that the Panel would need to be wider. Wouldn’t it be easier if the contents of the Panel would just automatically align themselves within the confines of that container?
Constraints let me solve these types of problems very easily. They also let me do so entirely through Flex Builder’s design view. Let’s revisit the code and screenshot with constraints added.
<mx:Application layout=”absolute” xmlns:mx=”http://www.adobe.com/2006/mxml”>
<mx:Panel
width=”275″
height=”150″
horizontalCenter=”0″
verticalCenter=”0″
layout=”absolute”
title=”Login”>
<mx:Label left=”10″ top=”12″ text=”Username:” />
<mx:TextInput left=”85″ right=”10″ top=”10″ />
<mx:Label left=”10″ top=”42″ text=”Password:” />
<mx:TextInput left=”85″ right=”10″ top=”40″ displayAsPassword=”true” />
<mx:ControlBar>
<mx:Button label=”Login” />
</mx:ControlBar>
</mx:Panel>
</mx:Application>

Now my dialog will stay centered in the application regardless of screen resolution. Additionally, the username and password Label and TextInput controls will also now stay where they are relative to the Panel regardless of the size of the Panel itself. As a side effect, this has also allowed me to round the numbers for the width and height of the Panel (used to be 274×148, and is now 275×150). Because the controls will now resize themselves appropriately these subtle changes become much easier to make.
Notice that all the X and Y properties are also no longer present, as the UI is now relative to other parts of the application.
There’s still one thing that bugging me about the UI though, and that’s the “Login” button itself which is aligned (by default) to the left in the ControlBar. Most operating systems align control buttons to the bottom right of a dialog. This is easy enough to change though, right? The ControlBar defaults to an HBox layout. While we could tell it to use constraints, this layout is working great for us as-is, save that pesky alignment.
Luckily for us, there’s a “horizontalAlign” style on the ControlBar container. I can flip that style inline, right on the tag, or I can put it in a Style block elsewhere in the source code. Most of the times we’ll pull our styles to a Style block, but then we’ll go one step further as well. We don’t like embedding all those styles inside the application itself, so we’ll externalize it to a CSS file. Now all our changes can be made in one centralized place.
What about those constraints though? Didn’t I mention that those were styles too? They are, and can be externalized in the same CSS. Let’s take a look at the application source code and screenshot one more time.
<mx:Application layout=”absolute” xmlns:mx=”http://www.adobe.com/2006/mxml”>
<mx:Style source=”constraints3.css” />
<mx:Panel
width=”275″
height=”150″
layout=”absolute”
title=”Login”>
<mx:Label text=”Username:” styleName=”userlabel” />
<mx:TextInput styleName=”userinput” />
<mx:Label text=”Password:” styleName=”passlabel” />
<mx:TextInput displayAsPassword=”true” styleName=”passinput” />
<mx:ControlBar>
<mx:Button label=”Login” />
</mx:ControlBar>
</mx:Panel>
</mx:Application>

The screenshot is almost identical to the previous examples save that our “Login” button is now aligned to the right - whew! The code has changed only a little as well, and in a good way. In place of exact constraints there’s now style names given to the controls where appropriate. All those pesky constraints that were tied directly to their specific control are now gone. Actually they are still there and it’s obvious that they are still being applied, but they’re now externalized into the CSS file. It’s in that CSS file where the magic really takes place, so let’s get a closer look.
ControlBar {
horizontal-align: right;
}
Label {
left: 10;
}
Panel {
horizontal-center: 0;
vertical-center: 0;
}
TextInput {
left: 85;
right: 10;
}
.userlabel {
top: 12;
}
.userinput {
top: 10;
}
.passlabel {
top: 42;
}
.passinput {
top: 40;
}
The first thing you should notice is that I’ve used CSS selectors where appropriate to specify styles for those controls en masse. When you get to the TextInput block, you’ll see that I’ve defined not fonts or colors, but left and right constraints. Since I want all my TextInput controls to be aligned vertically, and to maintain the same width (relation to the edges of the container), it makes sense to apply that styling at the block level. Managing the constraints for the TextInput’s relation to the top of the container is done in a CSS class statement.
The best part of all of this is the cascading nature of CSS. The “left” and “right” constraints on the TextInput block are also inherited with the class statements used to specify the “top”. We’ve been looking at the TextInput, but the same is also done with the Label selector and class statements. These are applied back in the MXML by using a “styleName” property on the controls.
The CSS selectors and class statements can also include font, color and other styling information.
Using the stylistic approach to constraints provides me with some pretty impressive capabilities. Let’s say that for whatever reason we decided that the Panel should actually be in the upper-left of the application. I can go into the CSS, exchange “vertical-center” and “horizontal-center” for “left” and “top” values and be done. An even better example might be if we want to rearrange the order of the Label and TextInput controls.
Simply by modifying the CSS I can completely change the order in which these controls appear. It could be as simple as vertical arrangement where I wanted “Password” to come before “Username”, but I could also put the Label controls on the right side of the TextInput controls. No hunting and pecking for inline properties, just simple CSS changes. A quick couple of double-clicks in the Flex Builder design view to change the labels to reflect their new positioning, and the rest is up to your imagination!
All the source code for these iterations is attached.
ControlBar {
horizontal-align: right;
}
Label {
right: 10;
}
Panel {
left: 10;
top: 10;
}
TextInput {
left: 10;
right: 85;
}
.userlabel {
top: 42;
}
.userinput {
top: 40;
}
.passlabel {
top: 12;
}
.passinput {
top: 10;
}

June 1st, 2006 at 10:26 am
just a note that recompilation is needed which is a small difference about html stylesheets and flex stylesheets.
July 8th, 2006 at 8:43 am
What “built-in” functionality am I loosing by not wrapping labels in fields within Form layout components? Validation? Required attributes?
August 8th, 2006 at 9:58 pm
Its Rox..
A Flex can supporting full specification css2 or css3 from w3c?
August 16th, 2006 at 6:41 am
wonderful post!
Can I translate it into Chinese and publish on the web? Of course, with links to the original post.
Thanks
November 2nd, 2006 at 10:54 am
Why don’t use HTML and CSS?
November 27th, 2006 at 1:11 am
Hi,
I want to pick piechart color from CSS. but I am not able to do it. pls help me
Sanjay
December 25th, 2006 at 9:51 am
Nice article. I just found this article after posting the PropertyBag class last night. Basically it lets you mix in properties into your stylesheets.
http://www.judahfrangipane.com/blog/?p=56
@The Doctor - you have so much more control and compatibility in Flex. I worked in HTML and CSS for 8 years as a professional web developer. I have switched to using Flex and I *enjoy* developing again and sleep peaceful at night.
February 6th, 2007 at 4:12 pm
Hi Kevin,
I found you via Computer Edge listings of Users Groups while actually looking for the Macromedia Group to get some CSS learning. Their website doesn’t come up. Might you know if they’re still functioning?
And is this Cold Fusion group?
If so, when is your next gathering, and where, please?
Thanks.
February 19th, 2007 at 7:01 am
Claudia,
You might try taking a look at the user group information on the Adobe web site.
http://www.adobe.com/communities/usergroups/
Thanks for reading,
Kevin
July 24th, 2007 at 2:24 pm
Hi.
Need a flex person.
racheal
July 24th, 2007 at 2:28 pm
Need a Flex developer.
are you open?
In San Franciscio.
racheal bailey
RGA Consulting
415 951 8051 ext. 1404
December 23rd, 2007 at 1:41 am
if I have several TextInputs and Buttons, then how can I relate their position in a css in flex? should I define some different class for each of them?
thank u
January 18th, 2008 at 4:34 am
Nice.
Thanks