Themes and Styles - Building the FindACab App - Hands-On Sencha Touch 2 (2014)

Hands-On Sencha Touch 2 (2014)

Part II. Building the FindACab App

Chapter 13. Themes and Styles

I once had a Sencha Touch 1 app in the Apple App Store and somebody gave me a very bad review. “This is a weird-looking iOS app.” What happened? Well, I just modified the default Sencha Touch stylesheet and gave all of the toolbars the same colors as native iOS components. The result was that the components almost looked like native, but they were just a little off. The users didn’t know that it was a mobile web application that was ported to native, so they expected the same experience as a native app, but it was just not the same. I learned from this that mobile web applications should either look and behave exactly the same as native apps, or they shouldn’t look like native at all. When the design is totally customized, people will get used to its design experience.

Sencha Touch Stylesheets

Times have changed. In Sencha Touch version 2.3, the framework ships with stylesheets that mimic native designs and experiences of all modern major devices (see Table 13-1). In addition to supporting iOS and Android, Sencha even works closely with the mobile device and browser makers like BlackBerry and Microsoft. Ahead of phone releases, Sencha gets access to test devices and style guides to make sure the Sencha Touch stylesheets look the same as native apps. When you create a production build of your app and you want to host it on the Web, it’s even possible to make use of the Sencha platform switcher. This switcher can make sure that the correct stylesheet will be shown for each platform. For example, the BB10 theme will be used when the platform is BlackBerry and show the Windows theme when the app is being viewed on Internet Explorer 10.

Table 13-1. Stylesheets that are shipped with Sencha Touch out of the box

Name

Filename

Description

Base

base.css

This is the Base theme, so you wouldn’t directly use it. Under the hood, it is used to define all Sencha Touch variables and mixins. The Base theme is inherited by all out-of-the-box stylesheets. See Figure 13-9.

Default

senchatouch.css

This is the default blue Sencha Touch stylesheet.

BlackBerry

bb10.css

This is the that mimics the BlackBerry 10 experience. See Figure 13-3.

Windows

wp.css

This is the Windows theme that mimics Windows Phone and Surface experience. See Figure 13-6.

Cupertino

cupertino.css

This is the that mimics the Apple iOS 7 experience. See Figures 13-1 and 13-8.

Cupertino Classic

cupertino-classic.css

This is the Cupertino theme that mimics the classic Apple iOS 6 experience. See Figures 13-2 and 13-7.

MountainView

mountainview.css

This is the that mimics the Android experience. See Figure 13-5.

Tizen

tizen.css

This is the Tizen theme that mimics the Tizen 2.1 Nectarine device; it has two tones, dark and light. See Figure 13-4.

The Cupertino theme is named for the city in California where the Apple headquarters are located

Figure 13-1. The Cupertino theme is named for the city in California where the Apple headquarters are located

The Cupertino Classic theme

Figure 13-2. The Cupertino Classic theme

The BlackBerry theme

Figure 13-3. The BlackBerry theme

The Tizen theme

Figure 13-4. The Tizen theme

Using Sass

Maybe you are building an application for a company, or you just want to create an awesome theme designed all by yourself. I can tell you that not only is this possible, but it’s even fairly easy. You don’t have to overrule the CSS (cascading style sheet) with nasty !importants. You can make use of the Sencha Sass themes, which provide a dynamic way of coding stylesheets.

Sass stands for “syntactically awesome style sheets,” a powerful CSS extension. And yes, it is awesome! I describe it as CSS infused with a lot of coffee and Red Bull, because it overcomes many of the shortcomings of CSS.

Sass is a preprocessor, which means that Sass files should be compiled to (minified) CSS files. A CSS file is the stylesheet your browser uses to display Sencha Touch components. (And that’s also the file that goes into your production build or server.) Therefore, Sass needs a compiler. You can compile Sencha Sass themes with Sass and Compass installed on top of Ruby (see Appendix A), but if you are not really into design, you can also use just the Sencha Cmd build process. A Sencha app build can compile Sass files too, but it just takes a little bit longer.

Sass has two syntaxes. The most commonly used syntax is known as SCSS (which stands for Sassy CSS), and is a superset of CSS3’s syntax. This means that every valid CSS3 stylesheet is valid SCSS as well. SCSS files use the extension .scss.

The second, older syntax is known as the indented syntax (or just .sass). Instead of brackets and semicolons, it uses line indentation to specify blocks. Files in the indented syntax use the extension .sass.

The Sencha themes are Sassy CSS files. You can combine CSS3 syntax with the amazing features of Sass. These features include nesting, defining variables (to set values and make math or color calculations), and creating mixins (little blocks of style rules to add Sass scripting like if/else or loop directives). If you are interested in learning Sass or Compass, my advice is to check out the official Sass website, The Sass Way, and Compass. They are really interesting, and Sencha uses some of these ideas to create its own themes. For example, Sencha ships with Global CSS variables and a handful of Sencha UI mixins. You will be amazed at how easy it is to create your own customized themes in just a few minutes.

In the next couple of sections, I will discuss how to use the out-of-the-box themes and how to create your own custom theme, with custom fonts and custom icons.

In this chapter, you’ll learn how to:

§ Use platform-specific out-of-the-box themes

§ Create your own custom theme

§ Incorporate custom fonts

§ Incorporate custom icons

§ Optimize your stylesheet for best performance

Using Platform-Specific, Out-of-the-Box Themes

When you generate a Sencha Touch app with Sencha Cmd, it will create an app.json file in the project root. This file contains all references to external JavaScript files, AppCache information, and references to used stylesheets.

By default, this file is linked to the app.css CSS file in your resources/css/ folder. It is a custom stylesheet that you can easily change with Sass, but by default it just extends from the Sencha Touch default theme. So, you will see only the default blue colors:

"css": [{

"path": "resources/css/app.css",

"update": "delta"

}],

The update property can be set to "delta" or "full". By default, the stylesheet will be cached in your Local Storage. When you make changes in your stylesheet while the app is already online, you can let the app autoupdate only the changes (deltas) or the full stylesheet.

You can let Sencha Touch detect the platform, and based on the platform, show matching resources. You can set it to use all out-of-the-box (platform-like) stylesheets, such as the BlackBerry 10 theme or the iOS- and Android-like themes, or you can set it up to utilize custom stylesheets:

"css": [{

"path": "touch/resources/css/sencha-touch.css",

"platform": ["desktop", "firefox"],

"theme": "Default",

"update": "delta"

},

{

"path": "touch/resources/css/wp.css",

"platform": ["ie10"],

"theme": "Windows",

"update": "delta"

},

{

"path": "touch/resources/css/bb10.css",

"platform": ["blackberry"],

"theme": "Blackberry",

"update": "delta"

},

{

"path": "touch/resources/css/cupertino.css",

"platform": ["ios"],

"theme": "Cupertino",

"update": "delta"

},

{

"path": "touch/resources/css/mountainview.css",

"platform": ["android"],

"theme": "MountainView",

"update": "delta"

},

{

"path": "touch/resources/css/tizen.css",

"platform": ["tizen"],

"theme": "Tizen",

"update": "delta"

}

],

To enable themes with the platform switcher, you will have to open the app.json file. In the css array, you can specify theme objects. These consist of a path to the available CSS, the platform to detect (see the list below), the name of the theme, and the update to specify either delta orfull. You can test each of these platforms by appending the platform parameter to your URL when running your app—for example, http://localhost/findacab/?platform=ie10.

The MountainView theme is named for a city in California where the Google headquarters are located

Figure 13-5. The MountainView theme is named for a city in California where the Google headquarters are located

The available platforms are:

§ androidj

§ blackberry

§ chrome

§ desktop

§ firefox

§ ie10

§ ios

§ ios-classic

§ phone

§ safari

§ tablet

§ tizen

The platform detection not only works for stylesheets, but also for JavaScript resources. See the js array in app.json. When you want to include platform detection in your Sencha Touch scripts, you can use platformConfig.

The Windows theme

Figure 13-6. The Windows theme

I have discussed how to implement an out-of-the-box (platform-specific) theme for your app. For a general app that would need to work on multiple devices, it’s good to rely on Sencha’s out-of-the-box themes. However, you may need to make your own custom theme. Creating a custom theme is ideal for when you want to showcase your own branding.

How the FindACab app looks on an iOS 6 iPad

Figure 13-7. How the FindACab app looks on an iOS 6 iPad

How the FindACab app looks on an iOS 7 iPad

Figure 13-8. How the FindACab app looks on an iOS 7 iPad

Creating Your Own Custom Theme

When you generate a Sencha Touch application with Sencha Cmd, it will also generate an empty theme for you. It is called the app.scss (Sass) file, and it can be found in the resources/sass folder. Aside from the app.scss, it will also contain a resources/fonts folder with a Pictos icon font and aconfig.rb Ruby file that sets the paths to the framework mixins and variables (see Example 13-1).

Example 13-1. config.rb

# Get the directory that this configuration file exists in

dir = File.dirname(__FILE__)

# Load the sencha-touch framework automatically.

load File.join(dir, '..', '..', '../../touch', 'resources', 'themes')

# Compass configurations

sass_path = dir

css_path = File.join(dir, "..", "css")

# Require any additional compass plug-ins here.

images_dir = File.join(dir, "..", "images")

output_style = :compressed

environment = :production

This empty custom theme extends from the Sencha Touch default theme. You can identify this by the @import lines at the top of the file, as shown in Example 13-2.

Example 13-2. resources/sass/app.scss

//1

@import 'sencha-touch/default';

@import 'sencha-touch/default/all';

//2

1

Write your Sencha variables here.

2

Insert your custom Sass code here.

This code imports the Sass variables and mixins from the default resources folders. These can be found in <touch>/resources/themes/Style Sheets/sencha-touch/.

Above the import of mixins, you can define Sencha variables. Underneath the mixins, you can start writing your own custom styles and mixins.

After writing your Sass theme, use the following command from the resources/sass folder to compile to app.css:

sencha ant sass

Sencha Cmd 4 and higher have the command sencha app watch. You can compare this with the Compass command compass watch. Sencha Cmd watches the app and every time you hit Save, Sencha Cmd builds your app and compiles your Sass stylesheets. When changes are detected, only the minimum amount of work necessary is performed to bring your app and its CSS up to date, saving you from rebuilding your Sass. It is so quick that when you navigate to your browser, the latest version is present. Nice!

Instead of extending from the default theme, you can extend from one of the other themes, as shown in Examples 13-3 through 13-7.

Example 13-3. Extend from the Windows theme

@import 'sencha-touch/windows';

@import 'sencha-touch/windows/all';

Example 13-4. Extend from the BlackBerry theme

@import 'sencha-touch/bb10';

@import 'sencha-touch/bb10/all';

Example 13-5. Extend from the MountainView Android theme

@import 'sencha-touch/mountainview';

@import 'sencha-touch/mountainview/all';

Example 13-6. Extend from the Cupertino iOS theme

@import 'sencha-touch/cupertino';

@import 'sencha-touch/cupertino/all';

Example 13-7. Extend from the Tizen theme

@import 'sencha-touch/tizen';

@import 'sencha-touch/tizen/all';

My suggestion is to stick with the default theme unless your design really has to be a spin-off of one of the device-specific themes. Also note that not all mixins and variables are the same for each theme. The only way to figure out which variables and mixins apply for the device-specific themes is by opening the Sass files; for example: <touch>/resources/themes/Style Sheets/sencha-touch/tizen.

It is also possible to extend from the Base theme (see Figure 13-9). There are no layout styles, like colors, gradients, margins, and padding set in this theme—just the absolute necessary styles for displaying your app. This theme is the starting point for all of the Sencha out-of-the-box themes (see Example 13-8).

Example 13-8. Extend from the Base theme; you have to style everything yourself

@import 'sencha-touch/base';

@import 'sencha-touch/base/all';

The base theme

Figure 13-9. The base theme

The advantage of extending from the base theme is that you don’t have to override default Sencha styles, because there are none. The base theme lays out only components; you have to style it all yourself. This reduces the file size of your Sassy CSS and therefore results in a much faster CSS compile. Themes will be compiled more quickly because you only need to compile your own custom styling. This makes writing stylesheets much more efficient.

If you want to create your own customized theme, it shouldn’t look like any of the out-of-the-box themes. But note that extending from the base theme probably will also take the most time to develop. If just changing some of the base colors is more than enough for you, my suggestion would be to extend from the default theme.

By extending from the Sencha default theme, you can create good-looking themes. There are Global-CSS variables—like base-color, neutral-color, font-family—that allow you to change the overall look and feel on the fly. Take a look at the API docs, and check theGlobal_CSS variables. For example, with the variable base-color, you can set the main base color for the default theme. Some of the Sencha components also have CSS variables to customize the look of your components. See, for example, Figure 13-10, which shows the variables for lists. Besides CSS variables, there are also a couple of UI component mixins that are quite powerful (see Table 13-2) and global mixins (see Table 13-3).

The list component has CSS variables to customize the look of your lists

Figure 13-10. The list component has CSS variables to customize the look of your lists

Table 13-2. Components that have component CSS variables and/or UI mixins

Component

Mixin

Ext.carousel.Carousel

sencha-carousel-indicator-ui($ui-label, $color, $gradient, $active-color, $active-gradient)

Ext.dataview.IndexBar

No mixins available

Ext.dataview.List

No mixins available

Ext.form.FieldSet

No mixins available

Ext.form.Panel

No mixins available

Ext.ActionSheet

No mixins available

Ext.Button

sencha-button-ui($ui-label, $color, $gradient)

Ext.Messagebox

No mixins available

Ext.Panel

No mixins available

Ext.Sheet

No mixins available

Ext.Toolbar

sencha-toolbar-ui($ui-label, $color, $gradient)

Ext.tab.Panel

sencha-tabbar-ui($ui-label, $bgcolor, $gradient, $color)

Table 13-3. Global CSS mixins

Mixin

Description

bevel-box($shadowtype)

Adds a small box shadow (or highlight)

bevel-by-background($bg-color)

Bevels the text based on background color

beveltext($shadowtype)

Adds a small text shadow (or hightlight)

elipsis()

Makes the element text overflow using ellipses to truncate text

icon($name, $character, $font-family)

Includes an icon to the stylesheet to be used on buttons or tabs

insertion($width, $height, $top, $left)

Adds basic styles to :before or :after CSS pseudoclasses

mask-by-background($bg-color, $percentage, $style)

Creates a background gradient for masked elements, based on the lightness of their background

toolbar-button($bg-color, $type)

Includes the default styles for toolbar buttons

With mixins, you can create different variants of button, toolbar, or carousel indicators. Out of the box, Sencha Touch ships with some mixins you can use directly on the component by setting the ui config on it. For example, Ext.ToolBar has the UIs light and dark; Ext.Button has the UIs normal, back, forward, round, plain, action, decline, and confirm; and the Ext.carousel.Carousel has the UIs light and dark. With the CSS mixins, you can create many more variants.

To implement a custom Sencha CSS mixin, you have to include the Sencha CSS mixin and pass in all the signature arguments (the first argument is always the custom UI name). Afterward, you can use the mixin in your JS component.

In the app.scss file, underneath the @import lines, specify:

@include sencha-button-ui('mycustombutton', #99A4AE, 'glossy');

@include sencha-toolbar-ui('alternative', #FF0000, 'glossy');

@include sencha-carousel-indicator-ui('gray', '#EFEFEF', 'glossy', '#FFFFFF',

'glossy');

Here’s how you can set the ui skin in your Sencha view classes:

var cancelBtn = Ext.create('Ext.Button',{

text: 'Cancel',

ui: 'mycustombutton'

});

var toolbar = Ext.create('Ext.Toolbar',{

title: 'My Green Glossy Toolbar',

ui: 'alternative'

});

var carousel = Ext.create('Ext.carousel.Carousel',{

ui: 'gray',

});

The FindACab App Stylesheet

The stylesheet for the FindACab app extends from the Sencha Touch default theme. It sets some of the Sencha Touch variables, includes a toolbar mixin, and has a custom font and icons (see Figure 13-11). If you are curious, check out the full code of the stylesheet in Appendix B. For now, let’s first discuss how to incorporate custom fonts and icons.

The FindACab app with a custom theme

Figure 13-11. The FindACab app with a custom theme

TIP

There are some great resources on Sass and CSS at the Sass website. To learn more about Sass, see The Sass Way. Learn Sass at Code School, and check out “Unleash Your Inner Picasso: Advanced Theming by Platform,” an online video tutorial by Robert Dougan.

Incorporating Custom Fonts

When you want to incorporate fonts in your theme, you can use @font-face. @font-face is a CSS technique that is often used to incorporate custom web fonts. Where system fonts will be visible only if they’re available on your OS, @font-face directly downloads the font from the Internet to display it. Of course, this can create a lot of headaches in terms of licenses and rights. But luckily, there are also a lot of free solutions. You can either download a @font-face kit (a package with multiple font extensions; see FontSquirrel) or use a font service (like TypeKit or Google Fonts).

TIP

Read more about @font-face on Paul Irish’s blog and download HTML5 @font-face kits from Font Squirrel or at font ex. You can also use a font service like Adobe Typekit or Google Fonts.

Let’s talk about downloading a @font-face kit. Unfortunately, none of the major browsers have come up with a single web font solution. Instead, they all go their own way. Therefore, you have to embed your web font with multiple extensions into your stylesheet so it works in all browsers. See Table 13-4, which lists font-face compatibility by browser as of October 2013.

Table 13-4. Cross-browser compatibility overview of font-face

Browser

TTF

EOT

WOFF

SVG

Google Chrome

X

_

X

X

Safari

X

_

X

X

Mobile Safari

X

_

X

X

IE10

_

X

X

_

Android Browser

X

_

_

X

BlackBerry Browser

X

_

X

X

Firefox

X

_

X

_

To incorporate @font-face fonts, create a fonts directory in the resources/css/stylesheets/ folder and copy the full custom web font folder into this directory.

Would you rather store the custom fonts with your Sass file? That’s possible, but then you have to manually copy over the fonts folder to your resources/css/styles folder. Hmmm, that might not be so ideal. Therefore, let’s automate this. Sencha Cmd has built-in Apache Ant integration.

Open build.xml in your root folder and right before the </project> closing tag add the following lines of code:

<target name="-after-build"/>

<target name="build"

depends="init,-before-build,-build,-after-build"

description="Copy over the font folder and remove temp files"/>

<copy todir="${basedir}/resources/css/stylesheets/fonts" overwrite="true">

<fileset dir="${basedir}/resources/sass/stylesheets/fonts">

<include name="**/*" />

</fileset>

</copy>

<copy todir="${build.dir}/resources/css/stylesheets/fonts" overwrite="true">

<fileset dir="${basedir}/resources/sass/stylesheets/fonts">

<include name="**/*" />

</fileset>

</copy>

<delete dir="${basedir}/${build.dir}"/>

When you’re building your application, the previous piece of code will automatically copy over the sass/stylesheets/fonts folder to the resources/css/stylesheets/fonts folder and to the same folder in the build directory.

The next step is implementing the font. You will set the name of the font that will be used throughout your stylesheet code, and you will embed all the font-types used for each different browser:

@font-face {

font-family: 'MyFont';

src: url('stylesheets/fonts/myfont.eot?22334');

src: url('stylesheets/fonts/myfont.eot?22334#iefix')

format('embedded-opentype'),

url('stylesheets/fonts/myfont.woff?22334') format('woff'),

url('stylesheets/fonts/myfont.ttf?22334') format('truetype'),

url('stylesheets/fonts/myfont.svg?22334#myfont') format('svg');

font-weight: normal;

font-style: normal;

}

You will have to add these lines of code on top of your Sass file.

Base64 Fonts

Maybe you know that images can be saved to Base64 strings (binary to ASCII text). It’s a technique that’s been used for years for sending email image attachments. If you are not familiar with Base64 strings, they look like this:

data:image/png;base64,<LONG BASE64 STRING WITH ENCODED DATA>"

An advantage of a string like this is offline storage and caching. The HTML5 Storage API can save only key/value pairs, and thus only character data, so you need to Base64-encode images to store them offline. Also, if an image is Base64 and placed directly in a stylesheet, then it can be cached with the stylesheet—yes, you can save data URLs for images in stylesheets too, but each URL in an image would be a request over the wire. You can also use Base64 encoding for fonts. No longer do you need to worry about hosting a .ttf, .svg, .woff, or .eot file somewhere and embedding it.

The trick is to get a Base64 font. Fortunately, you can generate one. Just download a @font-face kit and then upload each extension to an encoder (such as Opinionated Geek’s tool). It will present you with the Base64 string for each font file. These Base64 strings can be implemented in your Sass. See the solution code in Appendix B.

Once you have implemented the font in your Sass file, you will need to assign it to your components. This is easy. Just set a CSS class on a Sencha Touch component to target it from the CSS as follows:

{

xtype: 'button',

cls: 'mycustombutton'

text: 'mytext'

}

Here’s how to incorporate fonts in your Sass stylesheet:

.mycustombutton {

font-family: 'DroidSansRegular';

line-height: 1.6em;

}

Now that you know how to incorporate custom fonts in your Sencha Touch app, let’s take a look at incorporating custom icons. Icons in Sencha Touch are icon fonts, so this process is more or less similar to incorporating fonts. You’ll just need to make sure that a character maps to a particular font icon. Let’s check out the next technique.

Incorporating Custom Icons

Sencha Touch 2.3 uses the Pictos icon font. Before version 2.3, when you wanted to include icons, you had to implement them with a custom Sencha mixin. It had a whole resources folder full of black and white icon images. After using these mixins—for example, @include pictos-iconmask("wifi");—you’d use a Base64 string to generate a wifi icon into your CSS. To mask the white background away, in your Sencha Touch code, you had to enable the config iconMask to true.

That was a nice solution, though your CSS file became large and at the end all these icons are PNG pixel images, which means that you would lose quality on retina displays or while scaling or zooming. This is not the case when using vector icon fonts, such as the Sencha Touch out-of-the-box font, Pictos.

With an icon font, icons can be delivered as a font file and are mapped to (Unicode) characters. An icon font can be embedded with CSS like any other custom font.

By using a vector font to render your icons, you can scale them to any size and they will not lose any quality. It also improves load speed and file size; by using a font, you can load all the icons at once and use CSS to change their look for hover and active states. A font made up of a few icons will have a smaller file size than an image sprite with the same number of icons.

By default, Sencha Touch ships with a couple of Pictos icons that are mapped to an iconCls class name. To use these, just take the mapped class name, and set the iconCls on the tab and button components. See Figure 13-12 for an overview.

Out-of-the-box Pictos icons with their default iconCls mapped names

Figure 13-12. Out-of-the-box Pictos icons with their default iconCls mapped names

To incorporate a custom icon set into your design, you can set up your own custom icon font. You can download a ready-made icon font pack or you can create your own. Websites like Fontello.com (Figure 13-13) or Icomoon.io (Figure 13-14) let you choose your own icons and map these to characters and unicodes. Usually, you can specify the default font metrics (e.g., 16px), icon, and font names. Afterward, you download your custom font. The advantage of this technique is that your user won’t need to download icons that are not visible and your font size will be smaller. However, for you as a developer or dev team, it might be handy to create an overview icon test page (something like Figure 13-12) so it is clear which characters/Unicodes and icon names are being used.

When you specify your own custom icon font, there’s no need to ship your theme to include the Sencha Touch out-of-the-box Pictos icons, because this increases the download size of the theme for your users. It might be a good idea to turn Pictos and default fonts off. Just set the following variables on the top of your Sass file:

$include-pictos-font: false;

$include-default-icons: false;

Next, incorporate your custom icon font in the stylesheet. This works exactly the same as incorporating any other font: either convert the icon font to a Base64 string and implement this, or link to the font files in the resources/css/fonts/fontname folder.

Create your own custom font with Fontello.com

Figure 13-13. Create your own custom font with Fontello.com

Create your own custom icon font with IcoMoon.io

Figure 13-14. Create your own custom icon font with IcoMoon.io

Now that your icons are available in your theme, you need to assign them to each iconCls class. With an icon mixin—icon($iconCls, $character, $font-family)—this is easy:

@include icon('settings', 'y', 'myfontname');

Wow, how does that work? This mixin generates some CSS code that we will apply to a Sencha Touch component (like a button) by passing in an icon CSS class name, iconCls. The second argument is the mapped character (or Unicode string). It prepends this character as content in your app, right before the component. The last argument is the font-family name of the icon font, so it won’t display the readable alphabetical character, but rather the icon.

Some components have no icon mixin and iconCls class, although it is still possible to incorporate custom icons. It is even possible to change the colors or dimensions for these icons. See the following code, where I have changed the icon for the list disclosure button:

.x-list .x-list-disclosure:before {

content: ']';

font-family: 'myfontname';

color: #000;

}

Just refer to the CSS class of the component you want to target (you can inspect the component with your dev tools, or just add a new CSS class with the cls config, on the component). The trick is to use the :before or :after pseudo-selectors. This will dynamically insert the contentcharacter before (or after) the component in the DOM. Because these CSS rules also set the font-family to the icon font, an icon will be displayed (see Figure 13-15).

The FindACab app with custom icons; see for the full code of the stylesheet

Figure 13-15. The FindACab app with custom icons; see Appendix B for the full code of the stylesheet

This section explained how to incorporate your own custom icons, which creates a custom look with the big advantage that it reduces the file size of the stylesheet (why download all icons in a stylesheet, when you just need some of them?). The next section will discuss in more detail how to optimize your stylesheet.

TIP

Check out the Pictos icon font, the Ico Moon icon font, and the Fontello icon font. There’s more information about icon fonts at CSS-Tricks, and you can use Branah’s tool to convert text to unicodes and back.

Optimizing Your Stylesheet for Best Performance

If you want to optimize your Sencha Touch application for performance, optimizing your stylesheet is probably the easiest thing to do, and it’s very effective. Custom themes can easily grow in file size. A compiled Sencha Touch CSS of 1.5 MB is not uncommon. However, it can be annoying to put a 1.5 MB stylesheet online, especially when you are visiting (or downloading) your app on a slow cellular network connection, where every kilobyte counts.

Luckily, there are easy tricks that can save many kilobytes; here are the ones we’ll discuss in the next few pages:

§ Minify your stylesheet

§ Import only the required mixins in your stylesheet

§ Exclude experimental support for uncommon browsers

§ Exclude unusable default fonts and icons

Minifying Your Stylesheet

Set up the theme output style. There are a couple of settings you can choose from, shown in Table 13-5. You’ll need the setting :compressed to minify the CSS code and reduce the file size.

The compressed setting is not meant to be human-readable. It takes up the minimum amount of possible file size, having no whitespace except what is necessary to separate selectors. It also includes some other optimization tools, such as choosing the smallest representation for colors and removing comments.

Table 13-5. Overview of all style_output settings

Setting

Description

:compressed

To fully minify. This reduces the file size. CSS code is not readable.

:nested

For easy reading and debugging while CSS is indented; it will also display Sencha comments in your CSS.

:expanded

For easy reading and debugging. CSS is not nested. This looks more like it’s human made. It will also display Sencha comments in your CSS.

:compact

For reading and debugging. Compact style takes up less space than :nested or :expanded. Each CSS rule takes up one line; it will also display Sencha comments in your CSS.

You can set the output_style in the Compass configuration, which is a Ruby file and should be located in the app/resources/sass/ folder. Actually, if you generated your application with Sencha Cmd, the file will be there and already has a setup for minifying your CSS. If you did not generate your app with Sencha Cmd, just add the following line to your Compass Ruby config (config.rb):

output_style = :compressed

Feel free to experiment with the output_style setting to see the file size differences.

Importing Only the Required Mixins in Your Stylesheet

By default, when you generate an application with Sencha Cmd, it will import all available Sencha Touch mixins. See Example 13-9 (and thus CSS rules for every Sencha Touch component that exists in the Sencha framework). That might be a bit more than you need. If your application doesn’t use a carousel or slider form fields, it makes no sense to include all these CSS rules in your stylesheet.

Example 13-9. resources/sass/app.scss

@import 'sencha-touch/default';

@import 'sencha-touch/default/all';

Luckily, you can change this too. Usually, I comment out the @import line that imports all of the mixins. Then I list all the Sencha Touch mixins myself and I make sure Sencha Cmd is watching/compiling my Sass file (sencha app watch). Next, I start to comment out the mixins one by one, based on the classes I think are not being used. This is tricky, though; there are classes that you maybe never directly coded, but they are subclasses from other classes, such as Class or Panel. That’s why you should remove the mixins one by one, while watching your terminal to make sure you don’t get any compile errors.

The list of all the available Sencha Touch mixins can be found in touch/resources/themes/<theme-to-extend-from>/all.scss. They differ per Sencha theme. When I start listing the mixins in my own Sass file, I need to prefix them with the correct full path from the touch/resources/themes/folder, so my compiler won’t crash:

@import 'sencha-touch/default';

/*@import 'sencha-touch/default/all';*/

@import 'sencha-touch/default/src/_Class.scss';

@import 'sencha-touch/default/src/_Button.scss';

@import 'sencha-touch/default/src/_Panel.scss';

/*@import 'sencha-touch/default/src/_Sheet.scss';*/

@import 'sencha-touch/default/src/_MessageBox.scss';

@import 'sencha-touch/default/src/_Toolbar.scss';

/*@import 'sencha-touch/default/src/_Menu.scss';*/

/*@import 'sencha-touch/default/src/carousel/_Carousel.scss';*/

@import 'sencha-touch/default/src/form/_Panel.scss';

@import 'sencha-touch/default/src/form/_FieldSet.scss';

@import 'sencha-touch/default/src/field/_Field';

/*@import 'sencha-touch/default/src/field/_Checkbox.scss';*/

/*@import 'sencha-touch/default/src/field/_Radio.scss';*/

/*@import 'sencha-touch/default/src/field/_Search.scss';*/

/*@import 'sencha-touch/default/src/field/_Select.scss';*/

/*@import 'sencha-touch/default/src/field/_Slider.scss';*/

/*@import 'sencha-touch/default/src/field/_Spinner.scss';*/

/*@import 'sencha-touch/default/src/field/_TextArea.scss';*/

/*@import 'sencha-touch/default/src/dataview/_IndexBar.scss';*/

@import 'sencha-touch/default/src/dataview/_List.scss';

/*@import 'sencha-touch/default/src/picker/_Picker.scss';*/

/*@import 'sencha-touch/default/src/plugin/_ListPaging.scss';*/

/*@import 'sencha-touch/default/src/plugin/_PullRefresh.scss';*/

/*@import 'sencha-touch/default/src/slider/_Slider.scss';*/

@import 'sencha-touch/default/src/slider/_Toggle.scss';

/*@import 'sencha-touch/default/src/tab/_Panel.scss';*/

The previous example is used in the FindACab app. The Sass theme for the FindACab app won’t need CSS rules for unused components like textareas and carousels. Therefore, you don’t need to import the mixins.

Excluding Experimental Support for Uncommon Browsers

Compass makes it easy to code many of the CSS3 vendor-prefixed properties, without having to type it all out by hand. (No more typos!) For example, if you want to have rounded borders, you could use the Compass mixin border-radius, which will generate all of the vendor-prefixed CSS properties you need:

.round {

@include border-radius(5px);

}

This will generate this:

.round {

-moz-border-radius: 5px;

-webkit-border-radius: 5px;

-o-border-radius: 5px;

-ms-border-radius: 5px;

-khtml-border-radius: 5px;

border-radius: 5px;

}

Sencha makes use of a lot of these Compass mixins. This can easily increase your CSS file size. Maybe you are building your application only for iOS, or maybe you are displaying a custom theme only for certain platforms. In either case, there is no need to include all these vendor-prefixed properties. IE10 supports HTML5; a lot of CSS properties don’t need to be prefixed with -ms-; and the browsers Opera and Konquerer are not supported by Sencha Touch (yet).

That’s why it might be handy to disable the vendor-prefixed properties. The following code showcases how to disable them for the browsers Konquerer, Opera, and Internet Explorer. Add these variables to the top of your Sass stylesheet (app/resources/sass/app.scss), right before the import of the Sencha mixins:

$experimental-support-for-opera:false;

$experimental-support-for-khtml:false;

$experimental-support-for-microsoft :false;

@import "compass/css3";

Excluding Default Fonts and Icons

Maybe you are not using any icons at all, in which case there is no need to implement the Pictos icon font. Or maybe you are using just a few icons. In those scenarios, it might be better to incorporate your own icon font and disable the out-of-the-box Pictos font. By default, Pictos icons are enabled; disabling them can easily save up to 100KB.

Take a look at the following code. Add these variables to the top of your Sass stylesheet (app/resources/sass/app.scss), right before the import of the Sencha mixins:

$include-pictos-font: false;

$include-default-icons: false;

Summary

Now that you have a whole bag of tricks to reduce the CSS file size, you are ready to go live! Another great way of optimizing your application is to create production builds, a topic we will discuss in the next chapter.