If you define a style in only one place in a document, Flex uses that definition to set a property's value. However, an application can have several style sheets, local style definitions, external style properties, and style properties set directly on component instances. In such a situation, Flex determines the value of a property by looking for its definition in all these places in a specific order.
Lower-level styles take precedence over higher-level or external styles. If you set a style on an instance, and then set the style globally, the global style does not override the local style, even if you set it after you set the local style.
The order in which Flex looks for styles is important to understand so that you know which style properties apply to which controls.
Flex looks for a style property that was set inline on the component instance. If no style was set on the instance using an inline style, Flex checks if a style was set using an instance's setStyle() method. If it did not directly set the style on the instance, Flex examines the styleName property of the instance to see if a style declaration is assigned to it.
If you did not assign the styleName property to a style declaration, Flex looks for the property on type selector style declarations. If there are no type selector declarations, Flex checks the global selector. If all of these checks fail, the property is undefined, and Flex applies the default style.
In the early stages of checking for a style, Flex also examines the control's parent container for style settings. If the style property is not defined and the property is inheritable, Flex looks for the property on the instance's parent container. If the property isn't defined on the parent container, Flex checks the parent's parent, and so on. If the property is not inheritable, Flex ignores parent container style settings.
The order of precedence for style properties, from first to last, is as follows:
If you later call the setStyle() method on a component instance, that method takes precedence over all style settings, including inline.
Style definitions in <mx:Style> tags, external style sheets, and the defaults.css style sheet follow an order of precedence. The same style definition in defaults.css is overridden by an external style sheet that is specified by an <mx:Style source="stylesheet"/> tag, which is overridden by a style definition within an <mx:Style> tag.
The following example defines a type selector for Panel that sets the fontFamily property to Times and the fontSize property to 24. As a result, all controls inside the Panel container, as well as all subclasses such as Button and TextArea, inherit those styles. However, button2 overrides the inherited styles by defining them inline. When the application renders, button2 uses Arial for the font and 12 for the font size.
<?xml version="1.0"?>
<!-- skins/MoreContainerInheritance.mxml -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:Style>
Panel {
fontFamily: Times, "_serif";
fontSize: 24;
}
</mx:Style>
<mx:Panel title="My Panel">
<mx:Button id="button1" label="Button 1"/>
<mx:Button id="button2" label="Button 2" fontFamily="Arial" fontSize="12"/>
<mx:TextArea text="Flex has is own set of style properties which are
extensible so you can add to that list when you create a custom
component." width="425" height="400"/>
</mx:Panel>
</mx:Application>
The executing SWF file for the previous example is shown below:
Some Flex controls are made up of other components. For example, the DateField control includes a DateChooser subcomponent, the calendar that pops up when you click on the DateField's icon. The DateChooser subcomponent itself contains Button subcomponents for navigation and TextField subcomponents for labels.
Inheritable styles are passed from the parent control to the subcomponent. These include all text styles like color and textDecoration, as well as other inheritable styles. If you set the color style property on a DateField control, Flex applies that color to the text in the DateChooser subcomponent, too.
If you do not want an inheritable style property to be applied to the subcontrol, you can override the parent's style by defining a custom class selector. For example, to apply styles to the subcomponents of a ComboBox control, you can use the dropdownStyleName or textInputStyleName style properties to define custom selectors.
Most controls that have subcomponents have custom class selectors that apply styles to their subcomponents. In some cases, controls have multiple custom class selectors so that you can set style properties on more than one subcomponent.
The following example sets the color style property on the DateField control. To prevent this color from being applied to the DateChooser subcomponent, the DCStyle custom class selector overrides the value of the color style property. This custom class selector is applied to the DateField control with the dateChooserStyleName property.
<?xml version="1.0" encoding="utf-8"?>
<!-- styles/SubComponentStylesSelector.mxml -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:Style>
.DCStyle {
color:blue;
}
</mx:Style>
<mx:VBox>
<mx:VBox>
<mx:Label text="Overrides the color property of the subcontrol:"/>
<mx:DateField
id="dateField1"
yearNavigationEnabled="true"
color="red"
dateChooserStyleName="DCStyle"
/>
</mx:VBox>
<mx:HRule width="200" height="1"/>
<mx:VBox>
<mx:Label text="Applies the color property to the subcontrol:"/>
<mx:DateField
id="dateField2"
yearNavigationEnabled="true"
color="red"
/>
</mx:VBox>
</mx:VBox>
</mx:Application>
The executing SWF file for the previous example is shown below:
Noninheritable style properties are not passed from the parent component to the subcomponent. For example, if you customize the value of the cornerRadius property on the DateChooser control, the property does not affect the buttons that are subcomponents of the calendar. To pass that value to the subcomponent, you can modify the control's filter. Filters specify which style properties to pass to their subcomponents. A filter is an Array of objects that define the style properties that the parent control passes through to the subcomponent. Inheritable style properties are always passed; they cannot be filtered.
Most controls with subcomponents have at least one filter. For example, the ComboBox subcontrol has a dropDownStyleFilters property that defines which style properties the ComboBox passes through to the drop down List subcomponent.
Some controls with subcomponents have multiple filters. For example, the DateChooser control has separate filters for each of the buttons on the calendar: the previous month button (prevMonthStyleFilters), the next month button (nextMonthStyleFilters), the previous year button (prevYearStyleFilters), and the next year button (nextYearStyleFilters).
The filters properties are read-only, but you can customize them by subclassing the control and adding or removing objects in the filter Array.
The following example includes two DateField controls. The first DateField control does not use a custom filter. The second DateField control is a custom class that uses two custom filters (one for the properties of the next month button and one for the properties of the previous month button).
<?xml version="1.0" encoding="utf-8"?>
<!-- versioning/StyleFilterOverride.mxml -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" xmlns:comps="*">
<mx:HBox>
<mx:VBox>
<mx:Text width="200" text="Standard DateChooser control. Does not pass the cornerRadius property to the button subcomponents:"/>
<mx:DateChooser cornerRadius="10"/>
</mx:VBox>
<mx:VBox>
<mx:Text width="200">
<mx:text>
Custom DateChooser control. Passes the cornerRadius property
to the button subcomponents:
</mx:text>
</mx:Text>
<comps:MyDateChooser cornerRadius="10"/>
</mx:VBox>
</mx:HBox>
</mx:Application>
The executing SWF file for the previous example is shown below:
The following class extends DateChooser and defines custom filters Arrays for two of the button subcomponents:
package {
import mx.controls.DateChooser;
public class MyDateChooser extends DateChooser {
private static var myNextMonthStyleFilters:Object = {
"highlightAlphas" : "highlightAlphas",
"nextMonthUpSkin" : "nextMonthUpSkin",
"nextMonthOverSkin" : "nextMonthOverSkin",
"nextMonthDownSkin" : "nextMonthDownSkin",
"nextMonthDisabledSkin" : "nextMonthDisabledSkin",
"nextMonthSkin" : "nextMonthSkin",
"repeatDelay" : "repeatDelay",
"repeatInterval" : "repeatInterval",
"cornerRadius" : "cornerRadius" // This property is not normally included.
}
override protected function get nextMonthStyleFilters():Object {
return myNextMonthStyleFilters;
}
private static var myPrevMonthStyleFilters:Object = {
"highlightAlphas" : "highlightAlphas",
"prevMonthUpSkin" : "prevMonthUpSkin",
"prevMonthOverSkin" : "prevMonthOverSkin",
"prevMonthDownSkin" : "prevMonthDownSkin",
"prevMonthDisabledSkin" : "prevMonthDisabledSkin",
"prevMonthSkin" : "prevMonthSkin",
"repeatDelay" : "repeatDelay",
"repeatInterval" : "repeatInterval",
"cornerRadius" : "cornerRadius"
}
override protected function get prevMonthStyleFilters():Object {
return myPrevMonthStyleFilters;
}
}
}
The custom filters each include the following additional entry in the Array:
"cornerRadius" : "cornerRadius"
The cornerRadius property is not normally listed in the nextMonthStyleFilters and myPrevMonthStyleFilters Arrays. By adding it to these filter Arrays, you ensure that the property is passed from the parent control to the subcontrol, and is applied to the previous month and next month buttons.
You can also use filters to exclude properties that are normally passed through the subcomponent. You do this by removing those properties from the filter Array in the subclass.
<?xml version="1.0"?>
<!-- skins/SubComponentInheritance.mxml -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:Style>
TextInput {
fontSize:15;
}
</mx:Style>
<mx:RichTextEditor/>
<mx:ComboBox>
<mx:dataProvider>
<mx:String>2005</mx:String>
<mx:String>2006</mx:String>
<mx:String>2007</mx:String>
</mx:dataProvider>
</mx:ComboBox>
<mx:NumericStepper/>
</mx:Application>
Not all styles are inheritable, and not all styles are supported by all components and themes. In general, color and text styles are inheritable, regardless of how they are set (using CSS or style properties). All other styles are not inheritable unless otherwise noted.
A style is inherited only if it meets the following conditions:
You can apply noninheritable styles to all controls by using the global selector. For more information, see Using the global selector.
All themes support the inheritable and noninheritable text styles, but not all styles are supported by all themes. If you try to set a style property on a control but the current theme does not support that style, Flex does not apply the style.
Some styles are only used by skins in the theme, while others are used by the component code itself. The display text of components is not skinnable, so support for text styles is theme-independent.
|
Themes |
Style type |
Style |
|---|---|---|
|
All |
Inheritable |
color fontFamily fontSize fontStyle fontWeight leading textAlign textDecoration textIndent |
|
All |
Noninheritable |
paddingLeft paddingRight |
|
All |
Component-defined |
disabledColor headerHeight horizontalAlign horizontalGap paddingBottom paddingLeft paddingRight paddingTop rollOverColor selectionColor tabHeight tabWidth textRollOverColor textSelectedColor verticalAlign verticalGap |
|
Halo Aeon |
Component-dependent and all text styles |
backgroundGradientAlphas backgroundGradientColors borderAlpha borderColor borderSides borderThickness cornerRadius dateHeaderColor dateRollOverColor dropShadowEnabled fillAlphas fillColors footerColors headerColors highlightAlphas highlightColor roundedBottomCorners selectedDateColor shadowDirection shadowDistance strokeWidth themeColor todayColor |
For more information, About themes.
Many assets in the default Halo theme support a property called themeColor. You can set this property on the Application tag, and the color is applied throughout the Flex application on component assets, such as the Button control's border, the headers of an Accordion control, and the default shading of a ToolTip control's background.
In addition to color values such as 0xCCCCCC (for silver) or 0x0066FF (for blue), the following values for the themeColor property are valid:
The default value is haloBlue. The following example sets the value of themeColor to haloOrange:
<?xml version="1.0"?>
<!-- styles/ThemeColorExample.mxml -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" themeColor="haloOrange">
<mx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
[Bindable]
public var themes:ArrayCollection = new ArrayCollection(
[ "haloOrange", "haloBlue", "haloSilver", "haloGreen"]);
private function closeHandler(e:Event):void {
Application.application.setStyle("themeColor", ComboBox(e.target).selectedItem);
}
]]>
</mx:Script>
<mx:ComboBox dataProvider="{themes}" width="150" close="closeHandler(event);"/>
<mx:Button id="myButton" label="Click Me" toolTip="Click me"/>
</mx:Application>
The executing SWF file for the previous example is shown below: