Monday, November 17, 2008

Cascading Style Sheets: Flex 3 Style

One of the questions I was asked following one of my three presentations of Applying Flash to Java: Flex and OpenLaszlo at Colorado Software Summit 2008 was regarding Flex's support for Cascading Style Sheets (CSS). I answered that Flex does support CSS to some degree, but that he would likely not be able to apply his HTML .css files directly without some changes to Flex applications. In this blog entry I will cover some basics of applying CSS to Flex applications.

One of the advantages of Flex's CSS support is that many of the CSS techniques applied to non-Flex (HTML) web pages work similarly in Flex. In fact, Flex even supports both type selectors and class selectors with the same syntax one would use for these in DHTML/Ajax applications.

Before demonstrating Flex's CSS support, I'll first briefly review CSS use in traditional HTML pages. To begin with, a very simple external specification of styles to be applied is available in dustinstyle-html.css (shown next).


dustinstyle-html.css


/*
* Type Selectors.
*
* http://webdesign.about.com/od/cssselectors/qt/cssseltype.htm
*/

body
{
background-color: #EEEEEE;
color: #006666;
}
th
{
font-weight: bold;
color: #0000CC;
}


/*
* Class Selectors.
*
* http://webdesign.about.com/od/cssselectors/qt/cssselclass.htm
*/

.abbrev
{
text-align: center;
}
.state
{
font-weight: bold;
}
.title
{
font-weight: bold;
font-size: 125%;
color: #000033;
}



/*
* Pseudo Elements.
*
* http://webdesign.about.com/od/css1/p/blpseudo_frstlt.htm
*/

th:first-letter
{
font-size: 175%;
font-weight: bold;
}



The next code listing shows a simple web page, SimpleStyledPage.html, that makes use of the CSS specified styles shown above.

SimpleStyledPage.html


<html>
<head>
<title>Simple Styled Web Page</title>
<link href="assets/css/dustinstyle-html.css" rel="stylesheet" type="text/css" />
</head>
<body>

<div class="title">Simple Styled Web Page [CSS]</div>

<table>
<tr>
<th>State</th>
<th class="abbrev">Abbreviation</th>
<th>Capital City</th>
<th>Slogan</th>
</tr>
<tr>
<td class="state">Alabama</td>
<td class="abbrev">AL</td>
<td>Montgomery</td>
<td>Unforgettable</td>
</tr>
<tr>
<td class="state">Alaska</td>
<td class="abbrev">AK</td>
<td>Juneau</td>
<td>North! To Alaska</td>
</tr>
<tr>
<td class="state">Arizona</td>
<td class="abbrev">AZ</td>
<td>Phoenix</td>
<td>Grand Canyon State</td>
</tr>
<tr>
<td class="state">Arkansas</td>
<td class="abbrev">AR</td>
<td>Little Rock</td>
<td>The Natural State</td>
</tr>
<tr>
<td class="state">California</td>
<td class="abbrev">CA</td>
<td>Sacramento</td>
<td>Find Yourself Here</td>
</tr>
<tr>
<td class="state">Colorado</td>
<td class="abbrev">CO</td>
<td>Denver</td>
<td>Colorful Colorado</td>
</tr>
<tr>
<td class="state">Connecticut</td>
<td class="abbrev">CT</td>
<td>Hartford</td>
<td>We're Full of Surprises</td>
</tr>
</table>
</body>
</html>



The next two screen snapshots show the above web page both with and without the stylesheet previously listed applied.

HTML Page without CSS Styles Applied




HTML Page with CSS Styles Applied




We can specify CSS selectors for Flex that are the same as or very similar to those used in the HTML example above. The CSS file shown next, dustinstyle-flex.css, is modified from the previously listed one. The most significant changes were removal of the first-letter pseudo element because I don't think it is supported in Flex (anyone else know differently?), the replacement of the 'body' type selector with a 'basic' class selector, and the replacement of the 'th' (table header) type selector with a 'header' class selector.



dustinstyle-flex.css


/*
* Class Selectors.
*
* http://webdesign.about.com/od/cssselectors/qt/cssselclass.htm
*/

.abbrev
{
text-align: center;
}
.basic
{
background-color: #EEEEEE;
color: #006666;
font-size: 12;
}
.header
{
font-weight: bold;
color: #0000CC;
font-size: 14;
}
.state
{
font-weight: bold;
}
.title
{
font-weight: bold;
font-size: 18;
color: #000033;
}



Flex does support type selectors. However, because elements in the Flex MXML grammar tend to have different names than HTML element names (no <body> or <tr> elements in MXML for example), type selectors set up for HTML don't translate well directly to MXML type selectors. For my example, I simply converted the type selectors intended for HTML to class selectors for my MXML.

Here is what the dependent MXML code looks like:

SimpleStyledFlex.mxml


<mx:Application
xmlns:mx="http://www.adobe.com/2006/mxml"
styleName="basic">
<mx:Style source="assets/css/dustinstyle-flex.css"/>
<mx:Label text="Simple Styled Flex Application [CSS]"
styleName="title" />
<mx:Grid>
<mx:GridRow>
<mx:GridItem styleName="header">
<mx:Label text="State"/>
</mx:GridItem>
<mx:GridItem>
<mx:Label styleName="header" text="Abbreviation" />
</mx:GridItem>
<mx:GridItem styleName="header">
<mx:Label text="Capital City" />
</mx:GridItem>
<mx:GridItem>
<mx:Label styleName="header" text="Slogan" />
</mx:GridItem>
</mx:GridRow>
<mx:GridRow>
<mx:GridItem styleName="state">
<mx:Label text="Alabama" />
</mx:GridItem>
<mx:GridItem styleName="abbrev">
<mx:Label text="AL" />
</mx:GridItem>
<mx:GridItem>
<mx:Label text="Montgomery" />
</mx:GridItem>
<mx:GridItem>
<mx:Label text="Unforgettable" />
</mx:GridItem>
</mx:GridRow>
<mx:GridRow>
<mx:GridItem styleName="state">
<mx:Label text="Alaska" />
</mx:GridItem>
<mx:GridItem styleName="abbrev">
<mx:Label text="AK" />
</mx:GridItem>
<mx:GridItem>
<mx:Label text="Juneau" />
</mx:GridItem>
<mx:GridItem>
<mx:Label text="North! To Alaska" />
</mx:GridItem>
</mx:GridRow>
<mx:GridRow>
<mx:GridItem styleName="state">
<mx:Label text="Arizona" />
</mx:GridItem>
<mx:GridItem styleName="abbrev">
<mx:Label text="AZ" />
</mx:GridItem>
<mx:GridItem>
<mx:Label text="Phoenix" />
</mx:GridItem>
<mx:GridItem>
<mx:Label text="Grand Canyon State" />
</mx:GridItem>
</mx:GridRow>
<mx:GridRow>
<mx:GridItem styleName="state">
<mx:Label text="Arkansas" />
</mx:GridItem>
<mx:GridItem styleName="abbrev">
<mx:Label text="AR" />
</mx:GridItem>
<mx:GridItem>
<mx:Label text="Little Rock" />
</mx:GridItem>
<mx:GridItem>
<mx:Label text="The Natural State" />
</mx:GridItem>
</mx:GridRow>
<mx:GridRow>
<mx:GridItem styleName="state">
<mx:Label text="California" />
</mx:GridItem>
<mx:GridItem styleName="abbrev">
<mx:Label text="CA" />
</mx:GridItem>
<mx:GridItem>
<mx:Label text="Sacramento" />
</mx:GridItem>
<mx:GridItem>
<mx:Label text="Find Yourself Here" />
</mx:GridItem>
</mx:GridRow>
<mx:GridRow>
<mx:GridItem styleName="state">
<mx:Label text="Colorado" />
</mx:GridItem>
<mx:GridItem styleName="abbrev">
<mx:Label text="CO" />
</mx:GridItem>
<mx:GridItem>
<mx:Label text="Denver" />
</mx:GridItem>
<mx:GridItem>
<mx:Label text="Colorful Colorado" />
</mx:GridItem>
</mx:GridRow>
<mx:GridRow>
<mx:GridItem styleName="state">
<mx:Label text="Connecticut" />
</mx:GridItem>
<mx:GridItem styleName="abbrev">
<mx:Label text="CT" />
</mx:GridItem>
<mx:GridItem>
<mx:Label text="Hartford" />
</mx:GridItem>
<mx:GridItem>
<mx:Label text="We're Full of Surprises" />
</mx:GridItem>
</mx:GridRow>
</mx:Grid>
</mx:Application>



The next two screen snapshots show what the Flex application looks like with and without the application of style via CSS. Note that even the non-CSS version has some color to it thanks to Flex's default styling.


Flex Application without CSS Applied




Flex Application with CSS Applied




It is important to note that Flex only supports a subset of the CSS specification and so not all CSS features are implemented. As mentioned above, I am not aware of a Flex implementation of the first-letter pseudo element. Also, while the external CSS pages used by Flex can be largely the same as those used by HTML pages, the names of the selectors often cannot be the same. The reason for this is that it is CSS convention to use hyphenated names, but ActionScript needs the names to be expressed without hyphens (coding convention is to use camel case). The actual designations inside the styles can be hyphenated as demonstrated in the examples above, but the name by which they are referenced in the Flex code (for the styleName attribute and in the ActionScript) cannot use hyphens.

The Flex Style Explorer is an invaluable tool for playing with and learning about Flex's CSS support. This tool allows you to use color-picker style interface selections and see the CSS syntax required to implement the selected styles. Other good information on using Flex CSS support is available in the Flex 3 Help document Using Cascading Stylesheets.

This blog entry has attempted to demonstrate that styling Flex applications with CSS is straightforward and similar to what web developers using HTML and JavaScript are accustomed to. There certainly are some nuances to using CSS with Flex, but much of Flex's CSS support is exactly what developers from other web technologies will be familiar with.

No comments: