Home >
Typography Tricks for Flex 3
I'm sure I'm not alone in wishing I could take advantage of some of the yummy features in Flex 4 that make precise design and layout possible like, oh, Text Layout Framework (TLF). But some of us are working on large projects that have been in development too long to even think about switching over to Flex 4. Instead, we have to wring every ounce of precision and flexibility out of Flex 3 that we can.
Over the past few weeks, I've been presented with some interesting challenges by our designers, and I thought I'd share a few things I've discovered about putting text exactly where the designer wants it without creating the future maintenance headache or performance bottleneck that multiple text objects on the screen can cause.
Baseline positioning
If you're like me, you've probably read what the docs have to say about the baseline style
You can also use constraint-based layout to anchor any combination of the top, left, right, bottom sides, and baseline of a child at a specific distance from the Canvas edges...
And for some reason you've drawn the erroneous conclusion that you can anchor the baseline of a component at a specific distance from the Canvas edges. Natural mistake. We all make it. Here's the real scoop on baseline positioning.
Basic baseline positioning
What you'll see when you try to use baseline as documented is that the top of the text will be placed at that position, not the baseline. This is because of a bug in the undocumented CanvasLayout class that Canvas and Panel in absolute mode use to lay out their children, which miscalculates the y position of children that are not positioned relative to a ConstraintRow.
So the fix is simple, if kind of a pain. Add a ConstraintRow with a height of 100% to your container, then set the baseline of your Label, TextArea, or what have you to "theConstraintRow:15" (where 15 is the baseline position you want). Tip: you can set up a ConstraintRow in one Canvas or Panel and reuse it in others, by setting the constraintRows attribute to "{[theConstraintRow]}" instead of using a separate mx:constraintRows tag.
The problem with this fix is that it requires you to set up any Canvas or Panel that needs baseline positioning in MXML, and it's not very reusable. What if you want to do your baseline positioning through code?
Coding baseline positioning
I couldn't find even one example on setting up ConstraintRows/ConstraintColumns through code, but luckily, it's not that hard. To create the ConstraintRow, do something like this:
Then, when you want to set a baseline style on an IUIComponent, it looks something like this:
var cr:ConstraintRow = new ConstraintRow();
cr.percentHeight = 100;
cr.id = 'cr'
theCanvas.constraintRows = [cr];
var child:Label = new Label();
child.text = 'some text';
//if 15 is the baseline position you want
child.setStyle('baseline', 'cr:15');
theCanvas.addChild(child);
Note that if you don't set a height or percentHeight on your ConstraintRow that you will need to call initialized() on your ConstraintRow, so it will "stretch" properly around your content. Also note that invalidation of baseline positions that are relative to the Canvas height can be a little dicey for ConstraintRows set through code, so be prepared to get your hands dirty in the invalidation cycle if you're subclassing Canvas to support binding expressions in the baseline position of child components.
Multiple font sizes and weights in one text object
Our designers are quite fond of giving numeric values in one font weight and size and the units in another font weight and size. If it were just a font size change, or the change were from normal to bold font, it would be relatively easy to create a function to wrap the units in HTML tags for the htmlText property, like this:
public function get formattedValue():String {
return _value.toString() +
wrapUnits('meters', '<font size="-4"><b>|</b></font');
}
function wrapUnits(units:String, wrapper:String):String {
return wrapper.replace('|', units);
}
However, for whatever reason, Flex 3 does not support "weight" on the font tag in the htmlText property, so if the entire text object is set to bold, there is no way to "unbold" it in the middle of a string simply by using the limited tags that htmlText supports.
You may have encountered the tantalizing documentation on how to apply CSS to htmlText in a TextField, but been discouraged because you can't add a TextField directly to your Canvas Control. It turns out that you can apply a StyleSheet to a TextArea control, so if you can find a way to use a TextArea for your application, you can apply a styleSheet to your htmlText. Keep in mind that invalidation on this is, again, dicey, so if your text contains multiple lines and is dynamic, you might want to consider hard coding the height of the TextArea.
How about you? Have you had any adventures in Flex 3 typography lately?




Facebook Application Development
Thanks for the information shared here. that was an interesting and informative. I had a good experience by participating in the Adobe DevSummit in 2009 and looking forward to attend Adobe Flash Platform Summit 2010 as well. AFPS 2010 is the single largest Flash Platform conference in India which features topics like Flash, Flex, Flash Platform, AIR 2.5, Andriod, RIA, LiveCycles, PHP and more. I found the information about the conference from adobesummit.com
TextLayout frameword in Flex 4 is so resource hungry you are better off sticking with text fields, so these problems are here for a little while longer I'm afraid.