Posts tagged "css"

Comparing CSS Media Queries vs. Application Scaling

If you haven’t heard of either of these features in Flex 4.5, here’s a quick summary:

  • CSS Media Queries – Conditionally apply styles at runtime based on the DPI and/or OS of the target device
  • Application Scaling – When the application specifies an applicationDPI value, Flex applies a scale factor to the root application. The result is an application designed for one DPI value scales to look good on another device with a different DPI value.

The Flex 4.5 reference covers the differences in the two approaches to adapting a mobile application based on DPI. The documentation also spells out the steps it takes to implement each approach.

Testing both approaches is also straightforward. Flash Builder 4.5 can simulate screen resolution and DPI when you run your application in ADL on your PC. However, it’s not the same as seeing the results on an actual device at the real physical size.

I’ve put together some quick examples to demonstrate each approach and I’ve taken a few photos of actual devices to see the final result. I have 3 devices, going left to right:

  • Motorola Droid Pro, 320×480, DPI Classification = 160
  • HTC EVO, 480×800, DPI Classification = 240
  • iPod Touch 4th Gen, 640×960, DPI Classification = 320

The picture below shows 3 different applications:

  1. Application scaling is turned ON (applicationDPI=160) in the main Application tag. What this means is that I’ve designed my application with 160 DPI devices in mind. Flex will scale the entire application by a scale factor based on the runtimeDPI classification. From left to right you can see 1x, 1.5x and 2x scaling.
  2. Application scaling is turned OFF (applicationDPI is not set). At each DPI, I’ve adjusted my slider to a fontSize value that is readable based on the runtimeDPI of the device.
  3. Application scaling is turned OFF (applicationDPI is not set) but I’ve set single explicit fontSize value that is used for all 3 DPI classifications. Do not do this. As you can see, if you set an explicit fontSize for all 3 DPI classifications, you’ll run into issues at one end or the other. In this case, fontSize 16 is far too small on the iPod Touch.

 

What I should have done in the last scenario is define CSS style rules with media queries that select a proper fontSize based on the DPI of the device. I’ll use a simple label as my next example. The code below has scaling turned off, but this time I’ve defined a stylename with different fontSize values per-DPI classification.

In my ViewNavigatorApplication, I’ve turned off scaling:

<s:ViewNavigatorApplication> <!-- scaling is OFF when applicationDPI is not set-->
  ...
</s:ViewNavigatorApplication>

 

And in my View, I’ve defined a stylename with bold and italic styles that apply at all DPI classifications. After that, I’ve defined overrides using CSS media queries. Notice that I only supplied a new fontSize value for 240 and 320. The first rule is applied at all DPIs. I’m able to omit a 160 DPI-specific rule because it gets it’s fontSize style from the first rule.

<s:View>
<fx:Style>
@namespace s "library://ns.adobe.com/flex/spark";
/* applies to all DPIs */
.heading
{
  fontSize: 18;
  fontWeight: bold;
  fontStyle: italic;
}
@media (application-dpi: 240)
{
.heading
{
  fontSize: 28;
}
}
@media (application-dpi: 320)
{
.heading
{
  fontSize: 36;
}
}
</fx:Style>
...
<s:Label text="Heading Style, fontSize={fontSize}" styleName="heading"/>
</s:View>

 

The photo below shows my app running on all 3 devices. The Label with the “heading” stylename shows the correct DPI-specific fontSize on all 3 devices.

Share on Facebook

Video: How to Skin a TabbedViewNavigatorApplication

Developing skins for the TabbedViewNavigatorApplication isn’t too hard. You just have to know where to start. The diagram below shows the major pieces of a TabbedViewNavigatorApplication:

  1. TabbedViewNavigator – This is a skin part of the TabbedViewNavigatorApplication. The TabbedViewNavigator contains 1..N ViewNavigators. Each ViewNavigator is displayed as a tab in the tab bar.
  2. ViewNavigator – The ViewNavigator is used to push and pop views. Each button on the tab bar represents a single ViewNavigator. In a ViewNavigatorApplication (no tabs) there’s only 1 ViewNavigator.
  3. tabBar skin part – The tabBar skin part belongs to the TabbedViewNavigator. In the Mobile theme, the TabbedViewNavigatorSkin creates this skin part. What’s not so obvious is that this skin part is actually implemented as a ButtonBar, not as a TabBar. The tabBar can be any ButtonBarBase. We chose to use ButtonBar to implement first, middle and last button skins for our default Mobile theme.
  4. ButtonBarButton – Not much to say here. It’s a ButtonBarButton that gets it’s label and icon from the ViewNavigator.

Since the tabs are just a ButtonBar, we could declare a style rule using “s|ButtonBar” as the selector, but that would affect all ButtonBars in the application. Instead, we need to use advanced CSS as follows:

s|TabbedViewNavigator #tabBar
{
  chromeColor: #000000;
  color: #FFFFFF;
  skinClass: ClassReference("skins.TabbedViewNavigatorTabBarSkin");
}

Of course, the major detail I’m leaving out here is the actual TabbedViewNavigatorTabBarSkin. With a little work, I can get my application to look like this:


All it takes is a little bit of FXG and subclassing the existing skins used in the Mobile theme. Watch the video below for a quick explanation, or just download chirpie.fxp and try it out for yourself.

With the June update for Flex and Flash Builder coming soon, knowing your way around the Mobile theme, mobile skins and CSS will help you get started writing cross-platform applications quickly.

Share on Facebook

Tutorial: Styling the ActionBar

The ActionBar appears at the top of your application when you use ViewNavigatorApplication or TabbedViewNavigatorApplication in your project. It’s a skin part in the ViewNavigator that updates as Views are pushed and popped. Since it’s built into the default ViewNavigatorSkin, you don’t normally create it on your own in MXML. Because it’s built in, styling the ActionBar a little less obvious. So, I’d like to show you a few easy ways to customize the look of the ActionBar through CSS.

chromeColor

ActionBar supports the chromeColor style introduced with Spark in Flex 4. This example changes the ActionBar chromeColor to red for the entire application:

<?xml version="1.0" encoding="utf-8"?>
<s:ViewNavigatorApplication
xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
firstView="views.holrHomeView">
<fx:Style>
@namespace s "library://ns.adobe.com/flex/spark";
 s|ActionBar
{
chromeColor: #990000;
}
</fx:Style>
</s:ViewNavigatorApplication>

titleAlign

By default, the ActionBar title is left aligned. To change the horizontal alignment of the title text, set the titleAlign style to left, center or right.

s|ActionBar
{
  chromeColor: #990000;
  titleAlign: center;
}

defaultButtonAppearance

By default, the ActionBar uses flat-styled button skins for Buttons inside the navigationContent or actionContent of the application or view. These buttons are designed to be flush with the edges of the ActionBar.

The ActionBar has two built-in button styles that are controlled by the defaultButtonAppearance style. The second option is a beveled, iOS-styled look seen here:

s|ActionBar
{
  chromeColor: #990000;
  defaultButtonAppearance: beveled;
}
...
<s:navigationContent>
  <s:Button label="Back">
</s:navigationContent>
<s:actionContent>
  <s:Button label="Buy">
</s:actionContent>

Using defaultButtonAppearance=”beveled” is a shortcut for setting several different style values besides the Button skinClass values. These styles include padding, font sizes, and titleAlign.

Advanced CSS Selectors

Setting styles on the ActionBar will cause those styles to be inherited down to title, navigationGroup and actionGroup components. For this reason, the SDK has structured the ActionBar style rules in the Mobile theme to use advanced CSS selectors (see sdks/4.5.1/frameworks/projects/mobiletheme/defaults.css). This is done to isolate styles to specific components and skin parts. For example, you can see that the beveled button skins use a smaller font size than the ActionBar title.

Using advanced CSS selectors does have the drawback of being less obvious to override. Here’s an example of overriding the advanced CSS in the mobile theme to (1) use a normal and italic font for the title and (2) replace the arrow-styled back button in navigationContent with the same skin as buttons used in actionContent.

s|ActionBar
{
  chromeColor: #990000;
  defaultButtonAppearance: beveled;
}

s|ActionBar #titleDisplay
{
    fontWeight: normal;
    fontStyle: italic;
}

s|ActionBar.beveled s|Group#navigationGroup s|Button
{
    /* use the rounded button instead of the arrow button */
    skinClass: ClassReference("spark.skins.mobile.BeveledActionButtonSkin");
}

Next Steps

Use these CSS examples in your mobile projects for quick and easy styling. For more control over the look and feel of the ActionBar, apply your own custom skins.

Share on Facebook