Using Cascading Style Sheets

Cascading Style Sheets (CSS) are a standard mechanism for declaring text styles in HTML and most scripting languages. A style sheet is a collection of formatting rules for types of components or classes that include sets of components. Flex supports the use of CSS syntax and styles to apply styles to components.

In CSS syntax, each declaration associates a style name, or selector, with one or more style properties and their values. You define multiple style properties in each selector by separating each property with a semicolon. For example, the following style defines a selector named myFontStyle:

<?xml version="1.0"?>
<!-- styles/ClassSelector.mxml -->
<s:Application 
    xmlns:fx="http://ns.adobe.com/mxml/2009" 
    xmlns:mx="library://ns.adobe.com/flex/mx" 
    xmlns:s="library://ns.adobe.com/flex/spark">
    
    <fx:Style>
        .myFontStyle { 
            fontSize: 15;
            color: #9933FF;
        }
    </fx:Style>

    <s:VGroup>
        <!-- This button has the custom style applied to it. -->
        <s:Button id="myButton" styleName="myFontStyle" label="Click Me"/>

        <!-- This button uses default styles. -->
        <s:Button id="myButton2" label="Click Me"/>
    </s:VGroup>

</s:Application>

The executing SWF file for the previous example is shown below:

In this example, myFontStyle defines a new class of styles, so it is called a class selector. In the markup, you can explicitly apply the myFontStyle style to a control or class of controls.

A type selector implicitly applies itself to all components of a particular type, as well as all subclasses of that type. If you use type selectors, then you must be sure to define namespaces with the @namespace directive in the CSS so that Flex. This is because classes in different packages often share the same class name.

The following example defines a type selector named Button:
<?xml version="1.0"?>
<!-- styles/TypeSelectorAgain.mxml -->
<s:Application 
    xmlns:fx="http://ns.adobe.com/mxml/2009" 
    xmlns:mx="library://ns.adobe.com/flex/mx" 
    xmlns:s="library://ns.adobe.com/flex/spark">

    <fx:Style>
        @namespace s "library://ns.adobe.com/flex/spark";

        s|Button { 
            fontSize: 15;
            color: #9933FF;
        }
    </fx:Style>

    <s:VGroup>
        <s:Button id="myButton" label="Click Me"/>
        <s:Button id="myButton2" label="Click Me"/>
    </s:VGroup>

</s:Application>

The executing SWF file for the previous example is shown below:

Flex applies this style to all Button controls, and all subclasses of Button controls in the Spark namespace. If you define a type selector on a container, that style applies to all children of that container if the style is an inheriting style.

Flex also supports id, descendent, and pseudo selectors.

When discussing CSS in Flex, the subject of a selector is the right-most simple type selector in a potentially-complex selector expression. In the following example, the Button is the subject of the selectors:
VBox Panel Button#button12 { 
    color: #DDDDDD; 
} 
VBox.special Button { 
    color: #CCCCCC; 
} 
Button.special { 
    color: #BBBBBB; 
}

When determining styles for a new component instance, Flex examines all the parent classes looking for type selectors. Flex applies settings in all type selectors, not just the exact match. For example, suppose that class MyButton extends Button. For an instance of MyButton, Flex first checks for a MyButton type selector. Flex applies styles in the MyButton type selector, and then checks for a Button type selector. Flex applies styles in the Button selector, and then checks for a UIComponent type selector. Flex stops at UIComponent. Flex does not continue up the parent chain past UIComponent because Flex does not support type selectors for Sprite (the parent of UIComponent) or any of Sprite’s parent classes, up to the base Object class.

Note: The names of class selectors cannot include hyphens in Flex. If you use a hyphenated class selector name, such as my-class-selector, Flex ignores the style.

You can programmatically define new class and type selectors using the StyleManager class. You can access the top-level StyleManager by using the styleManager property of the Application object. For more information, see Using the StyleManager class.

About selector names

When applying style properties with CSS in a <fx:Style> block or in an external style sheet, the best practice is to use camel-case without hyphens for the style property, as in fontWeight and fontFamily (rather than font-weight and font-family). This matches the convention of using camel-case property names in MXML.

To make development easier, however, Flex supports both the camel-case and hyphenated syntax in style sheets, as the following example shows:

<?xml version="1.0"?>
<!-- styles/CamelCase.mxml -->
<s:Application 
    xmlns:fx="http://ns.adobe.com/mxml/2009" 
    xmlns:mx="library://ns.adobe.com/flex/mx" 
    xmlns:s="library://ns.adobe.com/flex/spark">

     <s:layout>
        <s:VerticalLayout/>
     </s:layout>
    
    <fx:Style>
        .myFontStyle { 
            fontSize: 15; /* Note the camelCase. */
        }

        .myOtherFontStyle { 
            font-size: 15; /* Note the hyphen. */
        }
    </fx:Style>

    <s:Button id="myButton" styleName="myFontStyle" label="Click Me"/>
    <s:Button id="myButton2" styleName="myOtherFontStyle" label="Click Me"/>

</s:Application>

The executing SWF file for the previous example is shown below:

In ActionScript or an MXML tag, you cannot use hyphenated style property names, so you must use the camel-case version of the style property. For the style name in a style sheet, you cannot use a hyphenated name, as the following example shows:

.myClass { ... } /* Valid style name */ 
.my-class { ... } /* Not a valid style name */

About namespaces in CSS

Some Spark and MX components share the same local name. For example, there is a Spark Button component (in the spark.components.* package) and an MX Button component (in the mx.controls.* package). To distinguish between different components that share the same name, you specify namespaces in your CSS that apply to types.

For example, you can specify that a particular selector apply to all components in the Spark namespace only. To specify a namespace in CSS, you declare the namespace with the @namespace directive, followed by the namespace’s library in quotation marks. The following example defines the Spark namespace and uses the “s” as an identifier:
@namespace s "library://ns.adobe.com/flex/spark";
The following are valid namespace directives in Flex 4 that refer to the manifests in the related SWC files:
  • library://ns.adobe.com/flex/spark

  • library://ns.adobe.com/flex/mx

If you do not use type selectors in your style sheets, then you are not required to use the @namespace rule.

After you specify a namespace’s identifier, you can use it in CSS selectors. The following example uses the Spark namespace for the Button components and the MX namespace for the Box containers:
<?xml version="1.0" encoding="utf-8"?>
<!-- styles/NamespaceIdentifierExample.mxml -->
<s:Application 
    xmlns:fx="http://ns.adobe.com/mxml/2009" 
    xmlns:mx="library://ns.adobe.com/flex/mx" 
    xmlns:s="library://ns.adobe.com/flex/spark" 
    xmlns:myComps="*"
    >
     <s:layout>
        <s:VerticalLayout/>
     </s:layout>
     
     <fx:Style>
          @namespace s "library://ns.adobe.com/flex/spark";
          @namespace mx "library://ns.adobe.com/flex/mx";

          s|Button {
               fontSize:16;          
          }
          
          mx|VBox {
               color:red;
          }
     </fx:Style>

     <mx:VBox>
          <!-- This Spark button is red, and has a fontSize of 16. -->
          <s:Button label="Click Me, Too"/>
      </mx:VBox>

</s:Application>

The executing SWF file for the previous example is shown below:

You can also specify that a particular selector apply to mixed nested namespaces. This is common if you are using descendant selectors. You can exclude an identifier, in which case the declared namespace becomes the default namespace. The following example uses the default namespace:
<fx:Style> 
    @namespace "library://ns.adobe.com/flex/spark"; 
    Button { 
        color: #990000; 
    } 
</fx:Style>
For custom components, you can define your own style namespace; that style namespace must match the component’s namespace. For example, components in the myComponents package use the style namespace “myComponents.*”, as the following example shows:
<?xml version="1.0"?>
<!-- styles/CustomComponentsNamespace.mxml -->
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
    xmlns:s="library://ns.adobe.com/flex/spark" 
    xmlns:mx="library://ns.adobe.com/flex/mx" 
    xmlns:comps="myComponents.*">

    <fx:Style>
        @namespace comps "myComponents.*";
        
        comps|MyButton {
            color:green;
        }
    </fx:Style> 

    <comps:MyButton label="Click Me"/>
</s:Application>

The executing SWF file for the previous example is shown below:

For custom components that are in the top level package, you can use an “*” for the namespace. However, you cannot use wildcard namespace prefixes, such as “*|” to match any namespace.

You can create your own namespace. This can be useful if you want to defines type selectors for custom components. The following example creates a new namespace for the classes in the mx.charts.chartClasses.* package. It then applies the new styles to just the DataTip class in that package:
<?xml version="1.0"?>
<!-- charts/DataTipStyles.mxml -->
<s:Application 
    xmlns:fx="http://ns.adobe.com/mxml/2009" 
    xmlns:mx="library://ns.adobe.com/flex/mx" 
    xmlns:s="library://ns.adobe.com/flex/spark" 
    creationComplete="srv.send()"
    height="600">

    <fx:Declarations>
         <!-- View source of the following page to see the structure of the data that Flex uses in this example. -->
         <mx:HTTPService id="srv" url="http://aspexamples.adobe.com/chart_examples/expenses-xml.aspx"/>
         <!-- To see data in an HTML table, go to http://aspexamples.adobe.com/chart_examples/expenses.aspx -->  
    </fx:Declarations>

    <fx:Style>
        @namespace chartClasses "mx.charts.chartClasses.*";    

        chartClasses|DataTip {
            fontFamily: "Arial";
            fontSize: 12; 
            fontWeight:bold;
            fontStyle:italic;            
        }
    </fx:Style>
    
    <s:layout>
        <s:VerticalLayout/>
    </s:layout>

    <s:Panel title="Bar Chart">
        <s:layout>
            <s:VerticalLayout/>
        </s:layout>
        <mx:BarChart id="myChart" 
            dataProvider="{srv.lastResult.data.result}" 
            showDataTips="true">
            <mx:verticalAxis>
                <mx:CategoryAxis categoryField="month"/>
            </mx:verticalAxis>
            <mx:series>
                <mx:BarSeries 
                    yField="month" 
                    xField="profit"
                    displayName="Profit"/>
                <mx:BarSeries 
                    yField="month" 
                    xField="expenses"
                    displayName="Expenses"/>
            </mx:series>
        </mx:BarChart>
        <mx:Legend dataProvider="{myChart}"/>
    </s:Panel>
</s:Application>

The executing SWF file for the previous example is shown below:

About inheritance in CSS

If you set an inheritable style property on a parent container, its children inherit that style property. For example, if you define fontFamily as Times for a Panel container, all children of that container will also use Times for fontFamily, unless they override that property. If you set a noninheritable style on a parent container, only the parent container uses that style; the children do not use that style. For more information on inheritable style properties, see About style inheritance.

In general, color and text styles are inheritable, regardless of which theme they are in (Spark or Halo) or how they are set (by using style sheets or the setStyle() method).

The following are exceptions to the rules of inheritance:

  • If you use the global selector in a CSS style definition, Flex applies those style properties to all controls, regardless of whether the properties are inheritable. For more information, see Using the global selector.

  • The values set in type selectors apply to the target class as well as its subclasses, even if the style properties are not inheritable. For example, if you define a Group type selector, Flex applies all styles in that selector to Group and VGroup controls because VGroup is a subclass of Group.

In general, you should avoid using type selectors for commonly-used base classes like Group. Group is a class that Spark skins are based on. Setting styles on the Group type selector might cause unexpected results because the skins will have styles applied that you might not oridinarily expect to apply.

The following example illustrates this issue. All labels and button labels are yellow, even though only one label and one button is explicitly in a group. The reason is that the LabelSkin and ButtonSkin classes that define the skins for the Label and Button components, are based on the SparkSkin class. The SparkSkin class is a subclass of Group.
<?xml version="1.0" encoding="utf-8"?>
<!-- styles/TypeSelectorInheritance.mxml -->
<s:Application 
    xmlns:fx="http://ns.adobe.com/mxml/2009" 
    xmlns:mx="library://ns.adobe.com/flex/mx" 
    xmlns:s="library://ns.adobe.com/flex/spark">
     <s:layout>
        <s:VerticalLayout/>
     </s:layout>
     
     <fx:Style>
          @namespace s "library://ns.adobe.com/flex/spark";
          @namespace mx "library://ns.adobe.com/flex/mx";

          s|Group {
               color:#FFCC33;          
          }
          
     </fx:Style>
     
     <s:VGroup>
        <s:Button label="This Button is in a VGroup and its label is yellow."/>
        <s:Label text="This Label is in a VGroup and its text is yellow."/>
     </s:VGroup>

     <s:Button label="This Button is not in a Group, but it is still yellow."/>     
     <s:Label text="This Label is not in a Group, but it is still yellow."/>

</s:Application>

The executing SWF file for the previous example is shown below:

CSS differences

There are some major differences in Flex between support of CSS and the CSS specification:

  • Flex supports subclassing selectors. For example, if you specify a Box type selector, Flex applies the styles to all subclasses of Box, including VBox and HBox. This applies to all classes in the Flex framework’s class hierarchy below UIComponent. In this case, UIComponent is considered a “stop class.”

  • Flex supports a subset of the style properties that are available in CSS. Flex controls also have unique style properties that are not defined by the CSS specification.

  • Flex controls only support styles that are defined by the current theme. If a theme does not use a particular style, applying that style to a control or group of controls has no effect. For more information, see About themes.

  • Flex style sheets can define skins for controls using the Embed keyword. For more information, see Skinning MX components.

  • The CSS 3 wildcard namespace prefix syntax of *| that matches any namespace (including no namespace) is not supported. For more information, see Using Cascading Style Sheets.

  • The universal selector scoped to a particular CSS namespace is not supported. Namespaces are not known at runtime in Flex and as such the universal selector remains universal no matter what namespace it is scoped to in CSS.

  • If you apply multiple class selectors to a component, the order of preference that the styles is applied is the order in which they appear in the styleName property’s space-delimited list, not the order in which they are defined in the CSS block or external style sheet.

  • The implementation of the CSS Media Query feature in Flex supports only the “screen” type. No other media types are supported.

About class selectors

Class selectors define a set of styles (or a class) that you can apply to any component. You define the style class, and then point to the style class using the styleName property of the component’s MXML tag. All components that are a subclass of the UIComponent class support the styleName property.

The following example defines a new style myFontStyle and applies that style to a Button component by assigning the Button to the myFontStyle style class:

<?xml version="1.0"?>
<!-- styles/ClassSelector.mxml -->
<s:Application 
    xmlns:fx="http://ns.adobe.com/mxml/2009" 
    xmlns:mx="library://ns.adobe.com/flex/mx" 
    xmlns:s="library://ns.adobe.com/flex/spark">
    
    <fx:Style>
        .myFontStyle { 
            fontSize: 15;
            color: #9933FF;
        }
    </fx:Style>

    <s:VGroup>
        <!-- This button has the custom style applied to it. -->
        <s:Button id="myButton" styleName="myFontStyle" label="Click Me"/>

        <!-- This button uses default styles. -->
        <s:Button id="myButton2" label="Click Me"/>
    </s:VGroup>

</s:Application>

The executing SWF file for the previous example is shown below:

You can apply multiple class selectors by separating them with a space in the styleName property. The order of preference that the styles is applied is the order in which they appear in the space-delimited list, not the order in which they are defined in the CSS block or external style sheet. The following example applies both class selectors to the first button:
<?xml version="1.0"?>
<!-- styles/MultipleStyleNames.mxml -->
<s:Application 
    xmlns:fx="http://ns.adobe.com/mxml/2009" 
    xmlns:mx="library://ns.adobe.com/flex/mx" 
    xmlns:s="library://ns.adobe.com/flex/spark">
    
    <fx:Style>
        .myFontStyle { 
            fontSize: 22;
        }
        .myOtherFontStyle {
            color: #9933FF;        
        }
    </fx:Style>

    <s:VGroup>
        <!-- This button has the custom style applied to it. -->
        <s:Button id="myButton" 
            styleName="myFontStyle myOtherFontStyle" 
            label="Click Me"/>

        <!-- This button uses default styles. -->
        <s:Button id="myButton2" label="Click Me"/>
    </s:VGroup>

</s:Application>

The executing SWF file for the previous example is shown below:

Class selector names must start with a period when you access them with the getStyleDeclaration() method, as the following example shows:

<?xml version="1.0"?>
<!-- styles/ClassSelectorStyleManager.mxml -->
<s:Application 
    xmlns:fx="http://ns.adobe.com/mxml/2009" 
    xmlns:mx="library://ns.adobe.com/flex/mx" 
    xmlns:s="library://ns.adobe.com/flex/spark">

    <fx:Style>
        .myFontStyle { 
            fontSize: 15;
            color: #9933FF;
        }
    </fx:Style>

    <fx:Script>
        <![CDATA[     
            public function changeStyles(e:Event):void {
                styleManager.getStyleDeclaration(".myFontStyle").setStyle("color",0x3399CC);
            }     
        ]]>
    </fx:Script>

    <s:Button id="myButton" label="Click Here" styleName="myFontStyle" click="changeStyles(event)"/>
  
</s:Application>

The executing SWF file for the previous example is shown below:

You do not precede the class selector with a period when you use the styleName property for inline styles.

About type selectors

Type selectors assign styles to all components of a particular type. When you define a type selector, you are not required to explicitly apply that style. Instead, Flex applies the style to all classes of that type. Flex also applies the style properties defined by a type selector to all subclasses of that type.

When you use type selectors, you are required to specify which namespace each type appears in with the @namespace directive.

The following example shows a type selector for Button controls:

<?xml version="1.0"?>
<!-- styles/TypeSelector.mxml -->
<s:Application 
    xmlns:fx="http://ns.adobe.com/mxml/2009" 
    xmlns:mx="library://ns.adobe.com/flex/mx" 
    xmlns:s="library://ns.adobe.com/flex/spark">

    <fx:Style>
        @namespace s "library://ns.adobe.com/flex/spark";

        s|Button { 
            fontSize: 15;
            color: #9933FF;
        }
    </fx:Style>

    <s:VGroup>
        <s:Button id="myButton" label="Click Me"/>
        <s:Button id="myButton2" label="Click Me"/>
    </s:VGroup>

</s:Application>

The executing SWF file for the previous example is shown below:

In this example, Flex applies the color style to all Spark Button controls in the current document, and all Button controls in all the child documents. In addition, Flex applies the color style to all subclasses of the Spark Button class.

You can set the same style declaration for multiple component types by using a comma-separated list of components. The following example defines style information for all Spark Button, TextInput, and Label components:

<?xml version="1.0"?>
<!-- styles/MultipleTypeSelector.mxml -->
<s:Application 
    xmlns:fx="http://ns.adobe.com/mxml/2009" 
    xmlns:mx="library://ns.adobe.com/flex/mx" 
    xmlns:s="library://ns.adobe.com/flex/spark">

     <s:layout>
        <s:VerticalLayout/>
     </s:layout>
        
    <fx:Style>
        @namespace s "library://ns.adobe.com/flex/spark";  

        s|Button, s|TextInput, s|Label { 
            fontStyle: italic;
            fontSize: 24;
        }
    </fx:Style>

    <s:Button id="myButton" label="Click Here"/>
    <s:Label id="l1" text="My Label"/>
    <s:TextInput id="ti1" text="Input text here"/>
</s:Application>

The executing SWF file for the previous example is shown below:

You can use multiple type selectors of the same name at different levels to set different style properties. In an external CSS file, you can set all Spark Button components to use the Blue color for the fonts, as the following example shows:

/* assets/SimpleTypeSelector.css */
@namespace s "library://ns.adobe.com/flex/spark";

s|Button { 
    fontStyle: italic;
    color: #99FF00;
}

Then, in a local style declaration, you can set all Buttons to use the font size 10, as the following example shows:

<?xml version="1.0"?>
<!-- styles/TypeSelectorWithExternalCSS.mxml -->
<s:Application 
    xmlns:fx="http://ns.adobe.com/mxml/2009" 
    xmlns:mx="library://ns.adobe.com/flex/mx" 
    xmlns:s="library://ns.adobe.com/flex/spark">

  <fx:Style source="../assets/SimpleTypeSelector.css"/>

  <fx:Style>
     @namespace s "library://ns.adobe.com/flex/spark";

     s|Button { 
        fontSize: 15;
     }
  </fx:Style>

  <s:Button id="myButton" label="Click Here"/>

</s:Application>

The executing SWF file for the previous example is shown below:

The local style declaration does not interfere with external style declarations. Flex applies only the style properties that you specified. The result of this example is that Spark Label controls that are children of the current document use Blue for the color and 10 for the font size.

All styles are shared across all documents in an application and across all applications that are loaded inside the same application. For example, if you load two SWF files inside separate tabs in an MX TabNavigator container, both SWF files share the external style definitions.

When you assign styles to a type selector, all subclasses of that selector’s type (the class) are affected by the styles. For example, if you create a type selector for Group, the styles are also applied to VGroup and HGroup instances because those classes are subclasses of Group.

Using compound selectors

You can mix class and type selectors to create compound style declarations. For example, you can define the color in a class selector and the font size in a type selector, and then apply both to a component:

<?xml version="1.0"?>
<!-- styles/CompoundSelectors.mxml -->
<s:Application 
    xmlns:fx="http://ns.adobe.com/mxml/2009" 
    xmlns:mx="library://ns.adobe.com/flex/mx" 
    xmlns:s="library://ns.adobe.com/flex/spark">

  <fx:Style>
     @namespace s "library://ns.adobe.com/flex/spark";
     
     s|Label { 
        fontSize: 10pt;
     }
     .myLabel { 
        color: Blue;
     }
  </fx:Style>

  <s:Label styleName="myLabel" text="This Label is 10pt Blue"/>

</s:Application>

The executing SWF file for the previous example is shown below:

If you later remove one of the selectors (for example, call the StyleManager class’ clearStyleDeclaration() method on the type or class selector), the other selector’s style settings remain.

Using id selectors

Flex supports using an id selector. Flex applies styles to a component whose id matches the id selector in the CSS. To define an id selector, specify the id of the component with a pound sign (#) followed by the id string. The id selector can be qualified by the type or by itself.

The following example shows two ways to use an id selector:
<?xml version="1.0" encoding="utf-8"?>
<!-- styles/CSSIDSelectorExample.mxml -->
<s:Application 
    xmlns:fx="http://ns.adobe.com/mxml/2009" 
    xmlns:mx="library://ns.adobe.com/flex/mx" 
    xmlns:s="library://ns.adobe.com/flex/spark">
     <s:layout>
        <s:HorizontalLayout/>
     </s:layout>
     
     <fx:Style>
          @namespace s "library://ns.adobe.com/flex/spark";
          @namespace mx "library://ns.adobe.com/flex/mx";

          s|Button {
               fontSize:16;          
          }
          
          #myButton2 {
               color:red;
          }
          
          s|Button#myButton3 {
               color:blue;
          }
     </fx:Style>
     
     <s:Button id="myButton1" label="Click Me"/>
     <s:Button id="myButton2" label="Click Me, Too"/>
     <s:Button id="myButton3" label="Click Me, Three"/>
</s:Application>

The executing SWF file for the previous example is shown below:

Using descendant selectors

Descendant selectors are applied to components in a document, depending on their relationship to other components in the document. A descendant selector lets you apply styles to a component based on whether they descend (are children, grandchildren, or great grandchildren) from particular types of components.

When a component matches multiple descendant selectors, it adopts the style of the most closely-related ancestor. If there are nested descendant selectors, the component uses the styles defined by the selector that most closely matches its line of ancestors. For example, a Spark Button control within a VGroup within another VGroup matches a descendant selector for “s|VGroup s|VGroup s|Button” rather than a descendant selector for “s|VGroup s|Button”.

The following example shows four selectors. The first class selector applies to all Button instances. The first descendant selector applies to the second button, because that Button’s parent is a VGroup. The second descendant selector applies to the third Button, because that Button is a child of an HGroup and a VGroup. The last descendant select applies to the last Button, because that Button is a child of a VGroup within a VGroup.
<?xml version="1.0" encoding="utf-8"?>
<!-- styles/CSSDescendantSelectorExample.mxml -->
<s:Application 
    xmlns:fx="http://ns.adobe.com/mxml/2009" 
    xmlns:mx="library://ns.adobe.com/flex/mx" 
    xmlns:s="library://ns.adobe.com/flex/spark">
     <s:layout>
        <s:VerticalLayout/>
     </s:layout>
     
     <fx:Style>
          @namespace s "library://ns.adobe.com/flex/spark";
          @namespace mx "library://ns.adobe.com/flex/mx";

          s|Button {
               fontSize:16;          
          }
          
          s|VGroup s|Button {
               color:red;
          }
          
          s|VGroup s|HGroup s|Button {
               color: blue;
          }

          s|VGroup s|VGroup s|Button {
               color: green;
          }
     </fx:Style>
     <!-- This button has a fontSize of 16. -->
     <s:Button label="Click Me"/>

     <s:VGroup>
          <!-- This button is red, and has a fontSize of 16. -->
          <s:Button label="Click Me, Too"/>
      </s:VGroup>

     <s:VGroup>
          <s:HGroup>
               <!-- This button is blue, and has a fontSize of 16. -->
               <s:Button label="Click Me, Also"/>
          </s:HGroup>
     </s:VGroup>

     <s:VGroup>
          <s:VGroup>
               <!-- This button is green, and has a fontSize of 16. -->
               <s:Button label="Click Me, Click Me!"/>
          </s:VGroup>
     </s:VGroup>
</s:Application>

The executing SWF file for the previous example is shown below:

Styles are applied only to components that appear in the display list. Descendant selectors are only applied if the ancestors also appear in the display list.

Descendant selectors work with all classes that implement the IStyleClient interface.

A descendant selector applies to a component as long as any parent class of that component matches the descendant selector. The following example shows that two Spark Button controls inherit the styles of the Group descendant selector, because their parents (VGroup and HGroup) are both subclasses of Group.
<?xml version="1.0" encoding="utf-8"?>
<!-- styles/CSSDescendantSelectorExample2.mxml -->
<s:Application    
    xmlns:fx="http://ns.adobe.com/mxml/2009" 
    xmlns:mx="library://ns.adobe.com/flex/mx" 
    xmlns:s="library://ns.adobe.com/flex/spark" 
    xmlns:myComps="*">
     <s:layout>
        <s:VerticalLayout/>
     </s:layout>

     <fx:Style>
          @namespace s "library://ns.adobe.com/flex/spark";
          @namespace mx "library://ns.adobe.com/flex/mx";
          
          s|Group s|Button {
               color:red;          
          }
     </fx:Style>
     <s:VGroup>
          <!-- This button is red, because VGroup is a subclass of Group. -->
          <s:Button label="Click Me"/>
     </s:VGroup>
     <s:HGroup>
          <!-- This button is also red, because HGroup is also a subclass of Group. -->
          <s:Button label="Click Me, Too"/>
     </s:HGroup>
</s:Application>

The executing SWF file for the previous example is shown below:

In general, you should avoid using the Group type selector in CSS. This is because all Spark skins use the SparkSkin class, which is a subclass of Group. As a result, Spark skins will inherit style properties from the Group type selectors, which might produce unexpected results.

Nested descendant selectors that set inheritable style properties also work for subcomponents. For example, a Label is a subcomponent of a Button control. It is responsible for rendering the text for the button’s label text.

The following example shows that the nested descendant selectors Button Label apply to a Button for inheritable style properties:
<?xml version="1.0" encoding="utf-8"?>
<!-- styles/SubComponentDescendantSelector.mxml -->
<s:Application 
    xmlns:fx="http://ns.adobe.com/mxml/2009" 
    xmlns:mx="library://ns.adobe.com/flex/mx" 
    xmlns:s="library://ns.adobe.com/flex/spark">
     <s:layout>
        <s:VerticalLayout/>
     </s:layout>
     
     <fx:Style>
          @namespace s "library://ns.adobe.com/flex/spark";
          @namespace mx "library://ns.adobe.com/flex/mx";

          s|Button s|Label {
               backgroundColor:#FFCC33;          
          }          
     </fx:Style>
     
     <!-- This button has a fontSize of 16. -->
     <s:Button label="Click Me"/>

</s:Application>

The executing SWF file for the previous example is shown below:

Using pseudo selectors

Pseudo selectors let you apply styles to a component when that component is in a particular state. The following example uses a pseudo selector to change the appearance of the button when it is in the up, down, and over states:

<?xml version="1.0"?>
<!-- styles/PseudoSelectorExample.mxml -->
<s:Application 
    xmlns:fx="http://ns.adobe.com/mxml/2009" 
    xmlns:mx="library://ns.adobe.com/flex/mx" 
    xmlns:s="library://ns.adobe.com/flex/spark" 
    xmlns:custom="*">
    <fx:Style>
        @namespace s "library://ns.adobe.com/flex/spark";
        @namespace mx "library://ns.adobe.com/flex/mx";
        
        s|Button:up {
            chromeColor: black;
            color: #FFFFFF;
        }

        s|Button:over {
            chromeColor: gray;
            fontWeight: "bold";
            color: #FFFFFF;
        }

        s|Button:down {
            chromeColor: blue;
            fontWeight: "bold";
            color: #FFFF66;
        }
    </fx:Style>

    <s:Button label="Click Me" x="10" y="35"/>
</s:Application>

The executing SWF file for the previous example is shown below:

For more information about states, see View states.

About selector precedence

In general, the following rules apply when determining which styles are applied:
  • Local styles override global styles (a style set inline takes precedence over a selector)

  • When styles have equivalent precedence, the last one applied takes precedence

  • The more specific style takes precedence over the more general style

The rules for determining precedence are complicated. The Flex rules follow the CSS rules that are defined by the W3C.

For more information, see CSS3 Selectors W3C specification.

Class selectors take precedence over type selectors. In the following example, the text for the first Button control (with the class selector) is red, and the text of the second Button control (with the implicit type selector) is yellow:

<?xml version="1.0"?>
<!-- styles/SelectorPrecedence.mxml -->
<s:Application 
    xmlns:fx="http://ns.adobe.com/mxml/2009" 
    xmlns:mx="library://ns.adobe.com/flex/mx" 
    xmlns:s="library://ns.adobe.com/flex/spark">
    
    <fx:Style>
        @namespace s "library://ns.adobe.com/flex/spark";

        .myclass { 
            color: Red;
        }

        s|Button { 
            fontSize: 10pt; 
            color: Yellow;
        }
    </fx:Style>

    <s:VGroup width="500" height="200">
        <s:Button styleName="myclass" label="Red Button"/>
        <s:Button label="Yellow Button"/>
    </s:VGroup>

</s:Application>

The executing SWF file for the previous example is shown below:

The font size of both buttons is 10. When a class selector overrides a type selector, it does not override all values, just those that are explicitly defined.

Type selectors apply to a particular class, as well as its subclasses and child components. In the following example, the color property for a VGroup control is blue. This means that the color property for the Button and Label controls, which are direct children of the VGroup control, is blue.

<?xml version="1.0"?>
<!-- styles/BasicInheritance.mxml -->
<s:Application 
    xmlns:fx="http://ns.adobe.com/mxml/2009" 
    xmlns:mx="library://ns.adobe.com/flex/mx" 
    xmlns:s="library://ns.adobe.com/flex/spark">

    <fx:Style>
        @namespace s "library://ns.adobe.com/flex/spark";

        s|VGroup { 
            color:blue 
        }
    </fx:Style>

    <s:VGroup width="500" height="200">
        <s:Label text="This is a Label control."/>
        <s:Button label="Click Me"/>
    </s:VGroup>

</s:Application>

The executing SWF file for the previous example is shown below:

If the same style property is applied in multiple type selectors that apply to a class, the closest type to that class takes precedence. For example, the MX VBox class is a subclass of Box, which is a subclass of Container. If there were Box and Container type selectors rather than a VBox type selector, then the value of the VBox control’s color property would come from the Box type selector rather than the Container type selector, as the following example shows:

<?xml version="1.0"?>
<!-- styles/ContainerInheritance.mxml -->
<s:Application 
    xmlns:fx="http://ns.adobe.com/mxml/2009" 
    xmlns:mx="library://ns.adobe.com/flex/mx" 
    xmlns:s="library://ns.adobe.com/flex/spark">

    <fx:Style>
        @namespace mx "library://ns.adobe.com/flex/mx";

        mx|Container {
            color:red 
        }

        mx|Box { 
            color:green 
        }
    </fx:Style>

    <mx:VBox width="500" height="200">
        <mx:Label text="This is a green label."/>
        <mx:Button label="Click Me"/>
    </mx:VBox>

</s:Application>

The executing SWF file for the previous example is shown below:

Not all style properties are inheritable. For more information, see About style inheritance.

Embedding resources in style sheets

You can use embedded resources in your <fx:Style> blocks. This is useful for style properties such as backgroundImage, which you can apply to an embedded resource such as an image file. The following example embeds an image in CSS:

<?xml version="1.0"?>
<!-- styles/EmbedInCSS.mxml -->
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
    xmlns:mx="library://ns.adobe.com/flex/mx" 
    xmlns:s="library://ns.adobe.com/flex/spark">

    <fx:Style>
        .style1 { 
            backgroundImage: Embed("../assets/butterfly.gif"); 
            backgroundAlpha: .2;
        }
    </fx:Style>
    
    <s:Panel title="BorderContainer Component Example"
            width="75%" height="75%" 
            horizontalCenter="0" verticalCenter="0"> 

        <s:BorderContainer 
            left="10" right="10" top="10" bottom="10"
            styleName="style1">
            <s:layout>
                <s:VerticalLayout 
                    paddingLeft="5" paddingRight="5" 
                    paddingTop="5" paddingBottom="5"/>
            </s:layout>
            <s:HGroup>
                <s:Button label="Button 1"/>
                <s:Button label="Button 2"/>
                <s:Button label="Button 3"/>
                <s:Button label="Button 4"/>
            </s:HGroup>
            <s:HGroup>
                <s:Button label="Button 5"/>
                <s:Button label="Button 6"/>
                <s:Button label="Button 7"/>
                <s:Button label="Button 8"/>
            </s:HGroup>
            <s:HGroup>
                <s:Button label="Button 9"/>
                <s:Button label="Button 10"/>
                <s:Button label="Button 11"/>
                <s:Button label="Button 12"/>
            </s:HGroup>
        </s:BorderContainer> 
    </s:Panel>
</s:Application>

The executing SWF file for the previous example is shown below:

For graphical Halo skins, you use the Embed statement directly in the style sheet, as the following example shows:

<?xml version="1.0"?>
<!-- skins/EmbedImagesTypeSelector.mxml -->
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
    xmlns:mx="library://ns.adobe.com/flex/mx" 
    xmlns:s="library://ns.adobe.com/flex/spark">

    <fx:Style>
        @namespace mx "library://ns.adobe.com/flex/mx";
        
        mx|Button {
            overSkin: Embed("../assets/orb_over_skin.gif");
            upSkin: Embed("../assets/orb_up_skin.gif");
            downSkin: Embed("../assets/orb_down_skin.gif");
        }
    </fx:Style>

    <mx:Button id="b1" label="Click Me"/>

</s:Application>

The executing SWF file for the previous example is shown below:

For programmatic Halo skins, you use the ClassReference statement, as the following example shows:

<?xml version="1.0"?>
<!-- skins/ApplyButtonStatesSkin.mxml -->
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
    xmlns:mx="library://ns.adobe.com/flex/mx" 
    xmlns:s="library://ns.adobe.com/flex/spark">
    
    <fx:Style>
        @namespace mx "library://ns.adobe.com/flex/mx";

        mx|Button {
            overSkin: ClassReference("ButtonStatesSkin");
            upSkin: ClassReference("ButtonStatesSkin");
            downSkin: ClassReference("ButtonStatesSkin");
        }
    </fx:Style>

    <mx:Button id="b1" label="Click Me"/>

</s:Application>

The executing SWF file for the previous example is shown below:

For more information about using the Embed keyword, see Embedding assets.

For Spark controls, you edit the skin class to add images and behaviors for certain states. For more information about skinning Spark components, see Spark Skinning.

For more information about skinning MX components, see Skinning MX components.

Using document properties in CSS

You can use document properties in your CSS with the PropertyReference keyword. The property must be public, or it must be defined in the same document as the CSS. For example, you can use a private variable in an imported CSS file, as long as you imported that CSS file in the same document in which the variable is declared.

If you change the value of the document property, the component’s style property is not updated, even if the document property is bindable. Changing the value of the document property will not update the control’s appearance because styles are not reapplied unless you explicitly call the setStyle() method or trigger a reapplication of the styles in some other way.

The following example defines the mySize variable and uses it in the CSS:
<?xml version="1.0"?>
<!-- styles/PropertyReferenceExample.mxml -->
<s:Application 
    xmlns:fx="http://ns.adobe.com/mxml/2009"    
    xmlns:mx="library://ns.adobe.com/flex/mx"     
    xmlns:s="library://ns.adobe.com/flex/spark">

  <!-- You can declare a property using this method, too: -->
  <!-- 
  <fx:Declarations>
    <fx:Number id="mySize">20</fx:Number>
  </fx:Declarations>
  -->
  
  <fx:Script>
    [Bindable]
    private var mySize:Number = 20;    
  </fx:Script>
  
  <fx:Style>
     @namespace s "library://ns.adobe.com/flex/spark";

     s|Button {
        fontSize: PropertyReference("mySize");
     }     
  </fx:Style>

    <!--Notice that when you click the button, the value of mySize increases,
         but the size of the font on the button's label does not. Style properties
         must be explicitly set, even if the property is bindable. -->
  <s:Button id="myButton" label="{mySize.toString()}" click="mySize+=2"/>

</s:Application>

The executing SWF file for the previous example is shown below:

Using media queries

Flex includes partial support for CSS media queries. In Flex, media queries let you conditionally apply styles based on the DPI and OS of the target device. You typically use this feature if you are developing for mobile or tablet devices that have different target DPIs. For example, if a tablet has a DPI of 300, then you can set the font size to one value. If a tablet has a DPI of 200, then you can set the font size to a different value.

Media queries use the values of the application-dpi and os-platform CSS properties to determine which styles to apply.

The syntax for using media queries is as follows:
@media [media_type] [application-dpi:180|240|320] [and|not|only] 
    [os-platform:"Android"|"IOS"|"Macintosh"|"Windows"|"Linux"]

The only supported value for the media_type property is screen. As a result, you do not need to specify the media type.

If you do not specify a value for the application-dpi or os-platform properties, then all are assumed. You can specify one or more resolutions or platforms by comma-separating their values.

The following example changes the font size and color based on the value of the applicationDPI property:
<?xml version="1.0" encoding="utf-8"?>
<!-- styles/MediaQueryExample.mxml -->
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
     xmlns:s="library://ns.adobe.com/flex/spark" 
     applicationDPI="320"
     creationComplete="initApp()">
    
    <fx:Style>
        @namespace s "library://ns.adobe.com/flex/spark";
        @namespace mx "library://ns.adobe.com/flex/mx";

        s|TextArea {
            fontSize: 12;
        }

        @media (application-dpi: 160) and (os-platform: "Windows"), (os-platform: "Macintosh"), (os-platform: "Linux") {
            s|TextArea {
                fontSize: 12;
                color: red;
            }
        }
        @media (application-dpi: 240) and (os-platform: "Windows"), (os-platform: "Macintosh"), (os-platform: "Linux") {
            s|TextArea {
                fontSize: 18;
                color: green;
            }
        }
        @media (application-dpi: 320) and (os-platform: "Windows"), (os-platform: "Macintosh"), (os-platform: "Linux") {
            s|TextArea {
                fontSize: 24;
                color: blue;
            }
        }
    </fx:Style>
    
    <fx:Script>
        private function initApp():void {
            myTextArea.text = "OS: " + Capabilities.os + "\n" 
                + "MFR: " + Capabilities.manufacturer + "\n" 
                + "DPI: " + applicationDPI;
        }
    </fx:Script>
    
    <s:TextArea id="myTextArea" width="100%"/>
    
</s:Application>

The executing SWF file for the previous example is shown below:

For more information and examples on using media queries in applications, see Support multiple screen sizes and DPI values in a mobile application.