You are currently browsing the category archive for the 'CSS' category.
Flex 3 makes it easy as pie to transform a series of images into a custom Button control.
First, create a CSS style declaration for your button, and define a different skin for each image you want to use. Even if you only have a single image, you’ll still want to implement the basic upSkin, downSkin, overSkin and disabledSkin style properties.
To embed an image asset in CSS, use the following syntax:
up-skin: Embed("pathTo/myImages/Up.png");
Once you’ve created your CSS style declaration, you’ll need to reference it in the styleName property of your Button control.
Finally, since we’ve replaced the default chrome with a custom set of images, the mouse cursors won’t behave like they would for a normal button. To fix this, we need to enable the buttonMode property and disable the mouseChildren property in the button.
That’s all there is to it!
Sample code for the CSS:
http://userflex.wordpress.privatepaste.com/d1JLaHSoi8
Sample code for the MXML:
http://userflex.wordpress.privatepaste.com/aaZFSzU9E0
The StyleManager class in Flex allows you to easily read and write individual style properties from the comfort of your AS3 code.
But it’s not as easy as it could be.
You still have to retrieve each style declaration, make sure they exist, and then either return or set the desired style property. It’s not a lot of work, but it’s repetitive, and we can do better.
Enter the StyleUtil class.
StyleUtil is an all-static class I created with methods to access and modify individual style properties.
There are two basic methods, setCSSStyle() and getCSSStyle(), as well as hex() and hexToString() methods for converting hexadecimal values.
Now, changing the background color of a Canvas container is as simple as calling:
StyleUtil.setCSSStyle ("Canvas", "backgroundColor", StyleUtil.hex (value));
Not too shabby, eh?
Full source code is available here:
http://userflex.wordpress.privatepaste.com/241rTkjoRl
As well as a few sample getters and setters:
http://userflex.wordpress.privatepaste.com/ceKcBegdpA
Update: Code snippets I’ve posted using Private Paste are randomly disappearing, so if the above link no longer exists, here’s a backup.
TabNavigator containers come with a handful of styles that allow you to customize the appearance of the tabs:
tabStyleName
Name of CSS style declaration that specifies styles for the tabs. The default value isundefined.firstTabStyleName
Name of CSS style declaration that specifies styles for the first tab. If this is unspecified, the default value of thetabStyleNamestyle property is used.lastTabStyleName
Name of CSS style declaration that specifies styles for the last tab. If this is unspecified, the default value of thetabStyleNamestyle property is used.selectedTabTextStyleName
Name of CSS style declaration that specifies styles for the text of the selected tab.
But sadly, you cannot easily specify a CSS style declaration for the selected tab. You can only specify a style for the text of the selected tab.
This sucks.
Luckily, there is a better way to customize the appearance of the tabs, without being constrained or limited by the styles mentioned above. You can skin them!
In the CSS for your application, create a new style declaration for your tabs. Then define values for any or all of the skin properties: skin, disabledSkin, downSkin, overSkin, upSkin, selectedDisabledSkin, selectedDownSkin, selectedOverSkin, selectedUpSkin.
Now this is where it gets beautiful. The values you specify for the skin properties can point to custom components OR embeddable assets!
You can use ClassReference() to specify custom components and Embed() to specify custom assets like images or SWFs.
What’s great about this solution is that you can also use the standard TabNavigator styles in tandem with the custom skins.
This means you can skin the tab backgrounds with a GradientCanvas container, for example, and use the tabStyleName and selectedTabTextStyleName styles to customize the tab fonts!
Update: I’ve posted sample code below that uses a Canvas container and some basic black-and-white styles to demonstrate how this works!
Sample code for the custom styles:
|
.tab { up-skin: ClassReference(”TabSkin”); down-skin: ClassReference(”TabSkin”); over-skin: ClassReference(”TabSkin”); selected-up-skin: ClassReference(”SelectedTabSkin”); background-color: #FFFFFF; font-weight: normal; corner-radius: 0; border-style: solid; .selectedTab font-weight: bold; corner-radius: 0; border-style: solid; |
Sample code for the tab skins:
|
package { import mx.containers.Canvas; public class TabSkin extends Canvas { override protected function updateDisplayList (w : Number, h : Number) : void { this.styleName = “tab”; super.updateDisplayList (w, h); } } package public class SelectedTabSkin extends Canvas super.updateDisplayList (w, h); } |
Sample code for the TabNavigator container:
|
<mx:TabNavigator id=”tabs” tabStyleName=”tab” selectedTabTextStyleName=”selectedTab” /> |
Runtime styles are great. They allow you to dynamically change the look-and-feel of your application, and they reduce the size of your deployed SWF.
But when you load your style SWF at startup, there is a potential delay between when your application is displayed and your runtime styles are applied.
Why does this matter? Because in that minute fraction of time your application is visible before your runtime styles are applied, the default Flex styles are visible. The result is a not-so-subtle flicker as your styles change.
Fortunately, there is an easy solution.
It turns out you can prevent the Flex preloader from disappearing until your runtime styles have been loaded. If you override the initialized setter in your main MXML file, the preloader will not disappear until you call super.initialized = true.
Sample code for loading runtime styles:
http://userflex.wordpress.privatepaste.com/140mdMhCvg
The Canvas layout container. We all know it, we all love it. Lets us place our components wherever we like. Such a good sport.
But the one aspect I dislike about the Canvas container is the lack of a background gradient. Why should buttons have all the fun?
After reading through the source code for the Canvas container and Button control, I realized creating a Canvas with a background gradient would be pretty easy, so long as I was willing to tinker around with the drawing API.
Which I was.
So how did I do it? I extended the Canvas container in a new AS3 class, and overrode the updateDisplayList() method. That’s it.
The beauty of this is that it doesn’t mess with the layout of the child components in the container. It just makes the background a whole lot prettier.
Sample code for the GradientCanvas:
|
package { import mx.containers.Canvas; import mx.styles.StyleManager; import mx.utils.ColorUtil; public class GradientCanvas extends Canvas { override protected function updateDisplayList (w : Number, h : Number) : void { super.updateDisplayList (w, h); // retrieves the user-defined styles var fillColors : Array = getStyle (”fillColors”); var fillAlphas : Array = getStyle (”fillAlphas”); var cornerRadius : Number = getStyle (”cornerRadius”); // converts the fill colors to RGB color values StyleManager.getColorNames (fillColors); // ready to draw! graphics.clear (); // draws the gradient drawRoundRect (0, 0, w, h, cornerRadius, fillColors, fillAlphas, verticalGradientMatrix (0, 0, w, h)); } } } |
You’ll notice in the code that I only check for the fillColors, fillAlphas and cornerRadius styles in my component. That’s all I really needed for my GradientCanvas container, but if you wanted to add support for borders and shadows you would simply add the styles and draw them as well.
Piece of pie.
I love Flex, but the default scrollbars are hideous. Sure, you can customize a couple of values in the CSS, the track and fill colors, etc. But those stupid arrow buttons are still there, sucking up the good vibes from the rest of your application.
So how do we get rid of them?
First, create a custom class that extends ProgrammaticSkin. Override the updateDisplayList() method in this class and leave it blank. Don’t even invoke the super.updateDisplayList() method!
Second, add a class reference to your CSS file for each of the up and down arrow skin properties.
VoilĂ ! The arrow buttons are gone!
Update: I’ve posted sample code below to replace the dead Private Paste URLs.
Sample code for the custom skin:
|
package { import mx.skins.ProgrammaticSkin; public class NoArrowSkin extends ProgrammaticSkin { override protected function updateDisplayList (w : Number, h : Number) : void { } } } |
Sample code for the custom styles:
|
ScrollBar { upArrowDisabledSkin: ClassReference(”NoArrowSkin”); upArrowDownSkin: ClassReference(”NoArrowSkin”); upArrowOverSkin: ClassReference(”NoArrowSkin”); upArrowUpSkin: ClassReference(”NoArrowSkin”); downArrowDisabledSkin: ClassReference(”NoArrowSkin”); downArrowDownSkin: ClassReference(”NoArrowSkin”); downArrowOverSkin: ClassReference(”NoArrowSkin”); downArrowUpSkin: ClassReference(”NoArrowSkin”); } |
