Skinning Spark containers

Spark defines two types of containers:
  • Skinnable containers

  • Non-skinnable containers

Both types of containers are in the spark.components.* package. Most Spark containers are skinnable. For example, the SkinnableContainer, Panel, and TitleWindow containers are skinnable. Skinnable containers subclass the SkinnableContainer class.

Spark groups are examples of containers that are not skinnable. They provide a lightweight mechanism that you use to perform layout. However, Spark groups do not support skinning to ensure that they add minimal overhead to your application. To modify the visual appearance of a Spark group, you can use the corresponding Spark container, which is skinnable. By contrast, all MX containers are skinnable.

Skinnable container skins are just like other component skins. They define a group that defines where the content children are laid out. This element has an ID of contentGroup. All skinnable containers have a content group. All visual children of a container are pushed into the content group and laid out using that group’s layout rules.

For a list of which containers are skinnable and/or scrollable, see About Spark containers.

Sizing Spark container skins

A common reason to skin a Spark container is to add a graphic element, such as a rectangle, to be the background of the container. You typically set its size by using the constraint properties or the percent size properties by using one of the following methods:
  • Constraints (setting top=0, bottom=0, left=0, right=0)

  • Percent sizes (setting height=100%, width=100%)

When the components are first drawn, constraint properties take precedence (so if you set them, then the dimensional properties are ignored). However, if you set the value of the constraint properties, but then later explicitly set the value of the percent size properties at runtime (for example, by setting the percentHeight property to 100), Flex honors the new settings.

Using constraint or percent size properties depends on the use case. In general, a skin resizes when the host component resizes. The choice of percent or constraint sizing is based on the resizing scenario. For example, if you want a label element to be always half as wide as the skin, then set the width property to 50%. If you want a label element to be always inset by 5 pixels, set the left and right properties to 5.

The resizable skin elements in the default Spark skins usually set the left and right properties. To specify their default size, they also set the width property. As a result, if the component size is not set in the application, the element’s width sets the default size of the skin and the component.

The following example from the ButtonSkin.mxml class shows that the default size of the Button control is the default size of its skin. This is calculated from the rectangle in the skin, and is 69 pixels wide and 20 pixels high:
 <s:Rect left="0" right="0" top="0" bottom="0" width="69" height="20" radiusX="2" radiusY="2"> 
    <s:stroke> 
        <s:LinearGradientStroke rotation="90" weight="1"> 
            <s:GradientEntry color="0x000000" alpha="0.5625" alpha.down="0.6375" /> 
            <s:GradientEntry color="0x000000" alpha="0.75" alpha.down="0.85" /> 
        </s:LinearGradientStroke> 
    </s:stroke> 
</s:Rect>

Another technique for designing resizable skins is to specify a minimum size for the skin. For more information, see Setting minimum sizes of a skin.

Adding borders to Spark containers

One common use of a custom Spark skin is to add a borders to a container. Borders can be simple boxes around the perimeter of a container, or they can define drop shadows, line styles, corner radii, and other properties of a border.

To add a simple rectangular border to a container’s skin, you add a Rect object. You can set the height and width of the Rect to 100% so that the skin sizes itself to the size of the container automatically, or you can set the offsets to 0.

The following example adds a simple 1-point, black line as a border around the container:
<?xml version="1.0" encoding="utf-8"?>
<!-- SparkSkinning/SimpleContainerBorderExample.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:SkinnableContainer id="myContainer" height="200" width="200" skinClass="mySkins.ContainerBorderSkin">
        <s:Button label="Click Me"/>
    </s:SkinnableContainer>

</s:Application>

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

The contentGroup container has left, right, top, and bottom offsets of 1. This lets the border display outside the content instead of sitting directly on top of the outside edges of container children. The custom skin class for this example is as follows:
<?xml version="1.0" encoding="utf-8"?>
<!-- SparkSkinning/mySkins/ContainerBorderSkin.mxml -->
<s:Skin 
    xmlns:fx="http://ns.adobe.com/mxml/2009"     
    xmlns:mx="library://ns.adobe.com/flex/mx" 
    xmlns:s="library://ns.adobe.com/flex/spark" 
    alpha.disabled="0.5">

    <fx:Metadata>
        [HostComponent("spark.components.SkinnableContainer")]
    </fx:Metadata> 
    
    <s:states>
        <s:State name="normal" />
        <s:State name="disabled" />
    </s:states>
        
    <s:Group id="contentGroup" left="1" right="1" top="1" bottom="1">
        <s:layout>
            <s:VerticalLayout/>
        </s:layout>
    </s:Group>

    <s:Rect left="0" right="0" top="0" bottom="0">
        <s:stroke>
            <s:SolidColorStroke color="0x000000" weight="1"/>
        </s:stroke>
    </s:Rect>

</s:Skin>

The container’s skin sets its constraint properties (top, bottom, left, and right) to 0, so the Rect object is set to the same size as the container.

To create a border with rounded corners in a skin, you set the values of the radiusX and radiusY properties of the Rect object. These properties define the number of pixels for the corners on the x and y axes of the Rect. The following example sets the radiusX and radiusY properties to 10 to round the corners of the container’s skin:
<?xml version="1.0" encoding="utf-8"?>
<!-- SparkSkinning/RoundedContainerBorderExample.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:SkinnableContainer id="myContainer" 
        height="200" width="200" 
        skinClass="mySkins.ContainerRoundedBorderSkin">
        <s:Button label="Click Me"/>
    </s:SkinnableContainer>

</s:Application>

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

The custom skin class for this example is as follows:
<?xml version="1.0" encoding="utf-8"?>
<!-- SparkSkinning/mySkins/ContainerRoundedBorderSkin.mxml -->
<s:Skin 
    xmlns:fx="http://ns.adobe.com/mxml/2009" 
    xmlns:mx="library://ns.adobe.com/flex/mx"     
    xmlns:s="library://ns.adobe.com/flex/spark" 
    alpha.disabled="0.5">

    <fx:Metadata>
        [HostComponent("spark.components.SkinnableContainer")]
    </fx:Metadata> 
    
    <s:states>
        <s:State name="normal" />
        <s:State name="disabled" />
    </s:states>
    
    <s:Group id="contentGroup" left="10" right="10" top="10" bottom="10">
        <s:layout>
            <s:VerticalLayout/>
        </s:layout>
    </s:Group>

    <s:Rect left="0" right="0" top="0" bottom="0" radiusX="10" radiusY="10">
        <s:stroke>
            <s:SolidColorStroke color="0x000000" weight="1"/>
        </s:stroke>
    </s:Rect>

</s:Skin>

You can add a border to a container by using the BorderContainer class. The BorderContainer class is a subclass of the SkinnableContainer class. Because you use CSS styles and class properties to control the appearance of the BorderContainer class, you typically do not create a custom skin for it.

The following example shows that the BorderContainer class takes the cornerRadius, borderColor, borderVisible, and borderAlpha style properties in addition to layout properties, which let you define a border similar to that shown in the previous example without skinning:
<?xml version="1.0" encoding="utf-8"?>
<!-- SparkSkinning/BorderContainerExample.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">
    
    <s:BorderContainer width="200" height="200"
        borderColor="0x000000" 
        borderAlpha="1" 
        cornerRadius="10" 
        borderWeight="1">
        <s:layout>
            <s:HorizontalLayout 
                paddingLeft="15" paddingRight="15" 
                paddingTop="15" paddingBottom="15"/>
        </s:layout>

        <s:Button label="Click Me"/>

    </s:BorderContainer>
    
</s:Application>

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

Because the border-related properties are styles, you can use CSS to define a consistent border across all instances of the BorderContainer class; for example:
<?xml version="1.0" encoding="utf-8"?>
<!-- SparkSkinning/BorderContainerStyleExample.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">
    
    <fx:Style>
        @namespace s "library://ns.adobe.com/flex/spark";
        
        s|BorderContainer {
            borderColor:#000000; 
            borderAlpha:1; 
            cornerRadius:10; 
            borderWeight:1;
        }       
    </fx:Style> 

    <s:BorderContainer width="200" height="200">
        <s:layout>
            <s:HorizontalLayout 
                paddingLeft="15" paddingRight="15" 
                paddingTop="15" paddingBottom="15"/>
        </s:layout>
        <s:Button label="Click Me"/>
    </s:BorderContainer>
    
</s:Application>

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

To add a border to a single instance of a container or group, you are not required to create a custom skin for the container. You can instead add a Rect graphic in the application itself. This is a process known as composition, where you are adding graphical elements to the application that change the appearance of controls in the application. Sometimes skinning gives a better abstraction because it distinguishes between visual children and content children.

For example, you can define MXML graphic tags fragment that draws the graphic elements that make up the border. These graphic elements are typically a stroke or fill (or both).

The following example draws a border around a VGroup that contains Button controls without using a custom skin class:
<?xml version="1.0"?> 
<!-- SparkSkinning/SimpleBorderExampleNoSkin.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:Group>
        <!-- border/background graphics -->
        <s:Rect width="100%" height="100%">
               <s:stroke>
                   <s:SolidColorStroke color="0x000000" weight="2"/>
               </s:stroke>
        </s:Rect>

        <!-- content of container -->
        <s:VGroup left="10" top="10" right="10" bottom="10">
            <s:Button label="Click Me"/>
            <s:Button label="Click Me"/>
        </s:VGroup>
    </s:Group>
 
</s:Application>

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

Adding drop shadows to Spark containers

To add a drop shadow to a Spark container, you use the DropShadowFilter class. You add the filter to one of the graphic elements defined on that container’s skin class. The DropShadowFilter class supports the alpha, angle, distance, and other properties that let you customize the appearance of the drop shadow. In addition, you add a fill to the graphic element. The fill defines the color of the drop shadow. These settings are all in the custom skin class and not in the main application.

The following example defines a drop shadow on the container’s skin:
<?xml version="1.0" encoding="utf-8"?>
<!-- SparkSkinning/DropShadowBorderExample.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:SkinnableContainer id="myContainer" 
        height="200" width="200" 
        skinClass="mySkins.DropShadowBorderSkin">
        <s:Button label="Click Me"/>
    </s:SkinnableContainer>

</s:Application>

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

The custom skin class for this example is as follows:
<?xml version="1.0" encoding="utf-8"?>
<!-- SparkSkinning/mySkins/DropShadowBorderSkin.mxml -->
<s:Skin 
    xmlns:fx="http://ns.adobe.com/mxml/2009" 
    xmlns:mx="library://ns.adobe.com/flex/mx" 
    xmlns:s="library://ns.adobe.com/flex/spark" 
    alpha.disabled="0.5">

    <fx:Metadata>
        [HostComponent("spark.components.SkinnableContainer")]
    </fx:Metadata> 
    
    <s:states>
        <s:State name="normal"/>
        <s:State name="disabled"/>
    </s:states>

    <!-- drop shadow -->
    <s:Rect left="0" top="0" right="0" bottom="0">
        <s:filters>
            <s:DropShadowFilter 
                blurX="20" blurY="20" 
                alpha="0.32" 
                distance="11" 
                angle="90"                 
                knockout="true"/>
        </s:filters>
        <s:fill>
            <s:SolidColor color="0x000000"/>
        </s:fill>
    </s:Rect>
    
    <!-- layer 1: border -->
    <s:Rect left="0" right="0" top="0" bottom="0">
        <s:stroke>
            <s:SolidColorStroke color="0x000000" alpha="0.50" weight="1"/>
        </s:stroke>
    </s:Rect>

    <s:Group id="contentGroup" left="0" right="0" top="0" bottom="0">
        <s:layout>
            <s:VerticalLayout/>
        </s:layout>
    </s:Group>
</s:Skin>

In this example, the drop shadow is the first element on the skin. You can use the depth property to change the ordering of the elements. This property determines the order in which items inside of containers are rendered. Spark containers order their items based on their depth property, with the lowest depth in the back, and the higher in the front. Items with the same depth value appear in the order they are added to the container.

A more efficient alternative to the DropShadowFilter class is to use the dropShadowEnabled property to add a drop shadow. For more information, see Using the dropShadowEnabled property

You can also add a drop shadow to any individual container in the application itself through composition. The downside to doing it this way is that the drop shadow is applied to a single instance of the container, and not all containers. It also removes the benefits of abstraction that skins provide.

Adding padding to Spark containers

Another common use of Spark skins is modify the padding of Spark containers.

To add padding, you can set the offset properties of the container’s content group. These properties are top, bottom, left, and right.

The following example sets the offsets of the contentGroup to 10 so that the contents of the container are padded by 10 pixels in all directions:
<?xml version="1.0" encoding="utf-8"?>
<!-- SparkSkinning/PaddedContainerBorderExample.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:SkinnableContainer id="myContainer" 
        height="200" width="200" 
        skinClass="mySkins.ContainerPaddedBorderSkin"
    >
        <s:Button label="Click Me"/>
    </s:SkinnableContainer>

</s:Application>

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

The custom skin class for this example is as follows:
<?xml version="1.0" encoding="utf-8"?>
<!-- SparkSkinning/mySkins/ContainerPaddedBorderSkin.mxml -->
<s:Skin 
    xmlns:fx="http://ns.adobe.com/mxml/2009" 
    xmlns:mx="library://ns.adobe.com/flex/mx" 
    xmlns:s="library://ns.adobe.com/flex/spark" 
    alpha.disabled="0.5">

    <fx:Metadata>
        [HostComponent("spark.components.SkinnableContainer")]
    </fx:Metadata> 
    
    <s:states>
        <s:State name="normal" />
        <s:State name="disabled" />
    </s:states>
    
    <s:Group id="contentGroup" left="10" right="10" top="10" bottom="10">
        <s:layout>
            <s:VerticalLayout/>
        </s:layout>
    </s:Group>

    <s:Rect left="0" right="0" top="0" bottom="0">
        <s:stroke>
            <s:SolidColorStroke color="0x000000" weight="1"/>
        </s:stroke>
    </s:Rect>

</s:Skin>

You can also add padding to the layout object. For example, the VerticalLayout object takes paddingLeft, paddingRight, paddingBottom, and paddingTop properties.

Specifying the layout in the skin changes the default layout for this container. However, you can set it on the container instance itself to override the default layout that you set in the skin.

Adding scroll bars to Spark containers

Spark containers do not have scroll bars by default. To add scroll bars to a Spark container, use the Scroller class.

To add scroll bars to a container’s skin class, you wrap the content group or other element in a Scroller tag. The child of a Scroller tag must implement the IViewport interface. This interface is implemented by Group and DataGroup, and some components such as the RichEditableText control.

To ensure that scroll bars appear, do not set explicit sizes on the group. If you set the size of the group explicitly, then that size becomes the size of the Group and no scroll bars will be shown.

The following example defines the size of the application, and sizes the container to a percent of the overall height and width. The scroller is constrained to the size of the viewport (in this case, the content group). Because the image is larger than the size of its parent, Flex displays scroll bars.
<?xml version="1.0" encoding="utf-8"?> 
<!-- SparkSkinning/ScrollbarContainerExample.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" height="200" width="200"> 
        
        <s:SkinnableContainer id="myContainer" 
            height="50%" width="50%" 
            skinClass="mySkins.ScrollBarContainerSkin"> 
            <s:Image source="@Embed(source='../assets/myImage.jpg')"/> 
        </s:SkinnableContainer> 
        
 </s:Application>

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

This example uses the following custom skin class:
<?xml version="1.0" encoding="utf-8"?>
<!-- SparkSkinning/mySkins/ScrollBarContainerSkin.mxml -->
<s:Skin 
    xmlns:fx="http://ns.adobe.com/mxml/2009" 
    xmlns:mx="library://ns.adobe.com/flex/mx" 
    xmlns:s="library://ns.adobe.com/flex/spark" 
    alpha.disabled="0.5">

    <fx:Metadata>
        [HostComponent("spark.components.SkinnableContainer")]
    </fx:Metadata> 
    
    <s:states>
        <s:State name="normal"/>
        <s:State name="disabled"/>
    </s:states>

    <s:Scroller height="100%" width="100%">    
        <s:Group id="contentGroup">
            <s:layout>
                <s:BasicLayout/>
            </s:layout>
        </s:Group>
    </s:Scroller>
</s:Skin>

The Scroller layout does not support the left/right/top/bottom constraints on the content group of the container. And in general, you should not explicitly set the height and width properties of the Scroller’s content group. Instead, you should let the content group size naturally.

You can use the minViewportInset property on the Scroller class to inset the viewport relative to its Scroller along the edges where a scroll bar does not already keep the viewport away from the edge. For example, if you set the minViewportInset property to 10, then the right edge of the viewport would be 10 pixels from the right edge of its scroller, unless the vertical scroll bar was visible. When a scroll bar is visible, the viewport and the scroll bar would not have any space between them.

Adding background fills and images to Spark containers

To add background fills and background images to a Spark container’s skin, you add a Rect or other graphic element and add the fill to that element.

To add a color fill, you add a graphic element that is a subclass of FilledElement and define a child fill tag. Subclasses of FilledElement include Rect, Ellipse, and Path. The fill must implement the IFill interface, which includes the BitmapFill, LinearGradient, RadialGradient, or SolidColor classes.

The following example defines three containers with three different fills:
<?xml version="1.0" encoding="utf-8"?>
<!-- SparkSkinning/BackgroundFillExample.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"
    width="700">
    
    <s:layout>
        <s:HorizontalLayout/>
    </s:layout>

    <s:SkinnableContainer id="myContainer" 
        height="200" width="200" 
        skinClass="mySkins.BackgroundFillSkin">
        <s:Button label="Basic Fill"/>
    </s:SkinnableContainer>

    <s:SkinnableContainer id="myContainer2" 
        height="200" width="200" 
        skinClass="mySkins.RadialBackgroundFillSkin">
        <s:Button label="Radial Gradient Fill"/>
    </s:SkinnableContainer>
    <s:SkinnableContainer id="myContainer3" 
        height="200" width="200" 
        skinClass="mySkins.LinearBackgroundFillSkin">
        <s:Button label="Linear Gradient Fill"/>
    </s:SkinnableContainer>

</s:Application>

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

The example uses the following custom skin class for the radial gradient fill:

<?xml version="1.0" encoding="utf-8"?>
<!-- SparkSkinning/mySkins/RadialBackgroundFillSkin.mxml -->
<s:Skin 
    xmlns:fx="http://ns.adobe.com/mxml/2009" 
    xmlns:mx="library://ns.adobe.com/flex/mx" 
    xmlns:s="library://ns.adobe.com/flex/spark" 
    alpha.disabled="0.5">

    <fx:Metadata>
        [HostComponent("spark.components.SkinnableContainer")]
    </fx:Metadata> 
    
    <s:states>
        <s:State name="normal" />
        <s:State name="disabled" />
    </s:states>

    <!-- layer 1: border -->
    <s:Rect left="0" right="0" top="0" bottom="0">
        <s:stroke>
            <s:SolidColorStroke color="0" alpha="0.50" weight="1" />
        </s:stroke>
    </s:Rect>

    <!-- background fill -->
    <s:Rect id="background" left="1" top="1" right="1" bottom="1">
        <s:fill>
            <s:RadialGradient>
                <s:entries>
                    <s:GradientEntry color="0xFFAABB" ratio="0" alpha="1"/>
                    <s:GradientEntry color="0xFFCCDD" ratio=".33" alpha="1"/>
                    <s:GradientEntry color="0xFFEEFF" ratio=".66" alpha="1"/>
                </s:entries>
            </s:RadialGradient>            
        </s:fill>
    </s:Rect>
    
    <s:Group id="contentGroup" left="10" right="10" top="10" bottom="10">
        <s:layout>
            <s:VerticalLayout/>
        </s:layout>
    </s:Group>
</s:Skin>

The example uses the following custom skin class for the basic background fill:

<?xml version="1.0" encoding="utf-8"?>
<!-- SparkSkinning/mySkins/BackgroundFillSkin.mxml -->
<s:Skin 
    xmlns:fx="http://ns.adobe.com/mxml/2009" 
    xmlns:mx="library://ns.adobe.com/flex/mx" 
    xmlns:s="library://ns.adobe.com/flex/spark" alpha.disabled="0.5">

    <fx:Metadata>
        [HostComponent("spark.components.SkinnableContainer")]
    </fx:Metadata> 
    
    <s:states>
        <s:State name="normal" />
        <s:State name="disabled" />
    </s:states>

    <!-- layer 1: border -->
    <s:Rect left="0" right="0" top="0" bottom="0">
        <s:stroke>
            <s:SolidColorStroke color="0" alpha="0.50" weight="1" />
        </s:stroke>
    </s:Rect>

    <!-- background fill -->
    <s:Rect id="background" left="1" top="1" right="1" bottom="1">
        <s:fill>
            <s:SolidColor id="bgFill" color="0xFF0000"/>
        </s:fill>
    </s:Rect>
    
    <s:Group id="contentGroup" left="10" right="10" top="10" bottom="10">
        <s:layout>
            <s:VerticalLayout/>
        </s:layout>
    </s:Group>
</s:Skin>

The example uses the following custom skin class for the linear background fill:

<?xml version="1.0" encoding="utf-8"?>
<!-- SparkSkinning/mySkins/LinearBackgroundFillSkin.mxml -->
<s:Skin 
    xmlns:fx="http://ns.adobe.com/mxml/2009" 
    xmlns:mx="library://ns.adobe.com/flex/mx" 
    xmlns:s="library://ns.adobe.com/flex/spark" 
    alpha.disabled="0.5">

    <fx:Metadata>
        [HostComponent("spark.components.SkinnableContainer")]
    </fx:Metadata> 
    
    <s:states>
        <s:State name="normal" />
        <s:State name="disabled" />
    </s:states>

    <!-- layer 1: border -->
    <s:Rect left="0" right="0" top="0" bottom="0">
        <s:stroke>
            <mx:SolidColorStroke color="0" alpha="0.50" weight="1"/>
        </s:stroke>
    </s:Rect>

    <!-- background fill -->
    <s:Rect id="background" left="1" top="1" right="1" bottom="1">
        <s:fill>
            <s:LinearGradient>
                <s:entries>
                    <s:GradientEntry color="0xFFAABB" ratio="0" alpha="1"/>
                    <s:GradientEntry color="0xFFCCDD" ratio=".33" alpha="1"/>
                    <s:GradientEntry color="0xFFFFFF" ratio=".66" alpha="1"/>
                </s:entries>
            </s:LinearGradient>            
        </s:fill>
    </s:Rect>
    
    <s:Group id="contentGroup" left="10" right="10" top="10" bottom="10">
        <s:layout>
            <s:VerticalLayout/>
        </s:layout>
    </s:Group>
</s:Skin>

You can also add a background fill to a content group, although the content group often defines an offset or padding properties. These constraints are applied to the background in addition to the content. As a result, you typically add the background fill to a graphic element that is set to the entire height and width of the container.

To add a background image, you can use the BitmapFill class or a BitmapImage fill. The following example adds a background with a BitmapFill object:
<?xml version="1.0" encoding="utf-8"?>
<!-- SparkSkinning/BackgroundFillExample.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>

    <s:SkinnableContainer id="myContainer" 
        height="256" width="206" 
        skinClass="mySkins.BitmapFillBackgroundSkin"
    >
        <s:Button label="Bitmap Fill"/>
    </s:SkinnableContainer>
</s:Application>

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

This example uses the following custom skin class:
<?xml version="1.0" encoding="utf-8"?>
<!-- SparkSkinning/mySkins/BitmapFillBackgroundSkin.mxml -->
<s:Skin 
    xmlns:fx="http://ns.adobe.com/mxml/2009" 
    xmlns:mx="library://ns.adobe.com/flex/mx" 
    xmlns:s="library://ns.adobe.com/flex/spark" 
    alpha.disabled="0.5">

    <fx:Metadata>
        [HostComponent("spark.components.SkinnableContainer")]
    </fx:Metadata> 
    
    <s:states>
        <s:State name="normal" />
        <s:State name="disabled" />
    </s:states>

    <!-- layer 1: border -->
    <s:Rect left="0" right="0" top="0" bottom="0">
        <s:stroke>
            <s:SolidColorStroke color="0" alpha="0.50" weight="3" />
        </s:stroke>
    </s:Rect>

    <!-- background fill -->
    <s:Rect id="background" left="3" top="3" right="3" bottom="3" alpha=".25">
        <s:fill>
            <s:BitmapFill source="@Embed(source='../../assets/myImage.jpg')"/>
        </s:fill>
    </s:Rect>
    
    <s:Group id="contentGroup" left="10" right="10" top="10" bottom="10">
        <s:layout>
            <s:VerticalLayout/>
        </s:layout>
    </s:Group>
</s:Skin>

In this example, the container is perfectly sized to fit the bitmap background plus the width of the border. In many cases, though, you will have to set properties on the fill to avoid tiling or apply clipping. For more information, see the BitmapFill class in the ActionScript 3.0 Reference for the Adobe Flash Platform.

The content group of the container’s skin is typically the last element defined in the skin class. This is because the skin’s layers are applied in the order in which they appear in the skin class. When a skin class has a background fill in a skin class, you add the content layer after it so that the content is not covered by the fill.

You can use the depth property, which gives you more control over the z-index. This lets you rearrange the appearance of the skin’s elements so that it is not determined by the child order.