(X) Hide this
    • Login
    • Join
      • Generate New Image
        By clicking 'Register' you accept the terms of use .

Windows Store apps in HTML and XAML: Work with style(s)

(0 votes)
Andrea Boschin
>
Andrea Boschin
Joined Nov 17, 2009
Articles:   91
Comments:   9
More Articles
0 comments   /   posted on Jul 15, 2013
Categories:   Windows 8

Tweet

Up to here, I have always talked about XAML versus HTML and about C# versus Javascript, comparing features and functionalities. Working in the HTML side of the story, there is another actor of which we have to be aware of. It is the CSS stylesheet that is automatically created, as a common point to contain user interface aspects that apply to the whole application.

It is a very common practice in HTML programming to set visual aspects of elements using a cascading style sheet and it is really important to centralize styles and make them much more maintainable. In my experience of trainer, moving to the XAML side of the story, the bad (but common) practice is to set properties directly on controls instead of creating styles. This comes probably from the use of tools that does not encourage the creation of styles but makes the "per-property approach" excessively easy. Styles are equally available in XAML and they are also slightly more powerful. In this article I would like to resume what it is a stylesheet and how is can be created in both HTML and XAML, to make it something of friendly.

Styles: how they work

Cascading Style Sheets in HTML exist since long time. The current release of browsers supports the CSS 3.0 specifications that have added many features that make CSS really powerful and effective. Inside of Windows Store Apps, in the HTML programming, CSS are still present and they are based on the same 3.0 specification.

CSS and XAML's Styles are both a collection of properties, declared in the form of a series of name and values. These properties are applied to the element referred by the style. The main difference between xaml and html is that CSS works on a specific set of properties not related with HTML attributes but XAML styles are applied directly to the properties of XAML elements. This make xaml much more flexible because each new element, imported using the xaml extesibility can get a style applied on it.

As the name suggests, CSS are applied using a cascading logic that follows a well known prioritization logic, that applies as follow:

style attribute > style tag > stylesheet files

This fallback chain states that, when you specify a style attribute directly on an element, it take priority over the one you specify inside a page using the <style> tag, and this take priority over the styles specified using a *.css file linked to the page. This precise fallback is really important because, thanks to its usage, it is really simple to create stylesheets that apply a common appearance to elements and that are overriden where it is required for some or all the aspects of the rule.

In XAML, styles also follows a similar chain of priority. They can be specified into the Resources section in the App.xaml or in every element in the Visual Tree with a Hierarchic model. When a Style is specified in a child it takes priority over the one that is defined on a parent element. And finally, the specification of an attribute has the highest priority overriding every style.

Additionally styles, both with HTML and XAML can be applied in various ways. They can be applied by classes, by element type and directly inline here is an example in HTML and XAML:

   1: .mybox { border: solid black 1px; background-color: red; }
   2:  
   3: div  { border: solid black 1px; background-color: red; }
   4:  
   5: <div style="border: solid black 1px; background-color: red;" />

Here is the same in XAML

   1: <Style x:Key="mybox" TargetType="Rectangle">
   2:    <Setter Property="Stroke" Value="Black" />
   3:    <Setter Property="Fill" Value="Red" />
   4:  </Style>
   5:  
   6: <Style TargetType="Rectangle">
   7:    <Setter Property="Stroke" Value="Black" />
   8:    <Setter Property="Fill" Value="Red" />
   9:  </Style>
  10:  
  11: <Rectangle>
  12:    <Rectangle.Style>
  13:      <Style TargetType="Rectangle">
  14:        <Setter Property="Stroke" Value="Black" />
  15:        <Setter Property="Fill" Value="Red" />
  16:      </Style>
  17:    <Rectangle.Style>
  18:  </Rectangle>

Both in CSS and in XAML the last syntax is strongly discouraged, because it strictly connect the style with the element and it is hard to be overriden. Using an external stylesheet instead, is a good practice for maintenability.

CSS have an additional way to be applied that is completely unknown to XAML. This is specifying an element name or, and this is the very power of CSS, using a selector that explores the DOM to reach the target element. There is a powerful syntax to query the DOM that is also used by tools like jQuery:

   1: #myboxname { border: solid black 1px; background-color: red; }
   2:  
   3: div[data-role='item'] > a:hover { color: red; }

The last syntax is a CSS selector that reaches every <a> element, contained in a <div>, when it is hovered by the mouse. This let you specify different states for each element, in a way that xaml simply does not recognize.

The real power of xaml styles instead comes from some specific features: first of all, a style's property is strictly typed and is able to specify every type of dependency property, also if it contains a complex datatype. As an example a style can specify a full new template that is able to completely change the structure and behavior of a control, or define a default data template that applies to a specific styled ItemsControl, moving the structure of an item out of the pages's XAML file.

Another great feature of styles in XAML is inheritance. Thanks to the BasedOn attribute, which connects styles together, you can create a sort of chain where very common properties are expressed in base styles and they are inherited by more specific styles. In HTML css there is not a similar feature but you are able to specify multiple classes to the same element, separating it with spaces. It is not so friendly as the BasedOn attribute in XAML because you move it the html page, but is someway useful and commonly used: An example in XAML:

   1: <Style x:Key="BaseTextStyle" TargetType="TextBox">
   2:   <Setter Property="FontFamily" Value="Verdana" />
   3:   <Setter Property="FontSize" Value="12" />
   4:   <Setter Property="Foreground" Value="Black" />
   5: </Style>
   6:  
   7: <Style x:Key="AlertTextStyle" TargetType="TextBox" BasedOn="{StaticResource BaseTextStyle}">
   8:   <Setter Property="Foreground" Value="Red" />
   9:   <Setter Property="FontWeight" Value="Bold" />
  10: </Style>

TextBlocks are a place where often the BasedOn attribute demontrates its usefulness. In this example, the BaseTextStyle centralizes the FontFamily specification and gives some default values for Foreground and FontSize. Each style inherits this specification and can override some or all of them. Let see something similar in CSS:

   1: <style>
   2:     .baseTextStyle { font-family: verdana; font-size: 12pt; color: #000; }
   3:     .alert { color: #f00; font-weight: bold; }
   4: <style>
   5:  
   6: <div class="baseTextStyle alert">My alert Text</div>

As you can see the connection between styles is made in HTML but with XAML it is made in the Style chain making it much more easy to maintain. Creation of theme thanks to this feature is straightforward.

Use styles for application theme

After this short introduction to the connection point between CSS and Styles, let see how we can structure styles in an application to make it readable and maintainable. This is not a really easy task and usually they are required some practical tries to start understand the real power of styles and begin to understand what is good for styles and what is not. Generally speaking, my feel is that there's a complete set of properties that may be easily styled and where it makes really sense. There are also another set of properties that may be styled for default values but that tipically have their values customized page by page. this includes Width and Height that much of the times are strictly related with the content of the page and they are, much of the times, customized in-place. Differently, properties like colors, fonts, thickness, margins and padding, alignment and (in xaml) templates, have a great advantage in being applied by style. Speaking for XAML you usually work creating a base set of resources and then make it available to the application using a styles hierarchy using the BaseOn attribute. The most simple example is for colors:

   1: <Color x:Key="NormalColor">#FF333333</Color>
   2: <Color x:Key="MediumColor">#FF888888</Color>
   3: <Color x:Key="AlertColor">#FFFF0000</Color>
   4:  
   5: <SolidColorBrush x:Key="NormalBrush" Color="{StaticResource NormalColor}"/>
   6: <SolidColorBrush x:Key="MediumBrush" Color="{StaticResource MediumColor}"/>
   7: <SolidColorBrush x:Key="AlertBrush" Color="{StaticResource AlertColor}"/>
   8:  
   9: <LinearGradientBrush x:Key="NormalToMediumBrush" StartPoint="0,0" EndPoint="1,0">
  10:     <GradientStop Color="{StaticResource NormalColor}" Offset="0" />
  11:     <GradientStop Color="{StaticResource MediumColor}" Offset="1" />
  12: </LinearGradientBrush>

With this snippet I define a simple palette made of instances of the Color class. This is the sole point where hexadecimal values are expressed. Then a set of "Brushes" uses the palette's color to create Brush's instances that can be used from styles. Thank's to this initial setup you are able to change a color for all the application in a single point. Also, and this is the real power of this structure, you can easily swap from a Solid color to a Gradient, manipulating only the styles, because they are simply "Brush" instances that are usually used by element's properties.

In CSS there is not a straightforward solution that emulates this structure. With plain CSS you have to write colors (but also recurring fonts, sizes and so on...) again and again for each style class. Fortunately you can use "less" that is a language built on top of css that does something similar to Typescripf for Javascript. To have less in Visual Studio you must install ASP.NET and Web Tools 2012.2 Update (http://weblogs.asp.net/scottgu/archive/2013/02/18/announcing-release-of-asp-net-and-web-tools-2012-2-update.aspx). then you can manually create a ".less" file in Windows Store Apps project and work as follow

   1: @NormalColor: #333333;
   2: @MediumColor: #888888;
   3: @AlertColor: #FF0000;

This three rows snippet does exacly the same as the previous XAML's styles does. It defines three variables where the color value is stored. Then you can use the variable name in place of the color in each style. The compiler does the magic converting it to the usual stylesheet. Unfortunately with CSS you cannot emulate the brush swapping. Infact CSS uses directly colors in styles and does not have a brush concept.

Now that the colors have been defined you can use them in styles. In this snippet I define a base style and the use it for application wide purposes and for specific styles:

   1: <Style x:Key="BaseTextStyle" TargetType="TextBlock">
   2:     <Setter Property="FontFamily" Value="Verdana" />
   3:     <Setter Property="Foreground" Value="{StaticResource NormalBrush}" />
   4: </Style>
   5:  
   6: <Style x:Key="AlertTextStyle" TargetType="TextBlock" BasedOn="{StaticResource BaseTextStyle}">
   7:     <Setter Property="Foreground" Value="{StaticResource AlertBrush}" />
   8: </Style>
   9:  
  10: <Style TargetType="TextBlock" BasedOn="{StaticResource BaseTextStyle}" />

Firstly I define a "BaseTextStyle" with default font and foreground (its color is taken by the palette). Then I define an "AlertTextStyle" overriding the foreground property in red. Finally I also define an implicit style based on the BaseTextStyle. This one will not be used directly in code but should be directly applied by default to all the elements, thanks to the implicit style.

To get something similar in CSS you have to write this, in a LESS file:

   1: @NormalColor: #333333;
   2: @MediumColor: #888888;
   3: @AlertColor: #FF0000;
   4:  
   5: .BaseTextStyle {
   6:     font-family: Verdana;
   7:     color: @NormalColor;
   8: }
   9:  
  10: .AlertTextStyle {
  11:     .BaseTextStyle;
  12:     color: @AlertColor
  13: }
  14:  
  15: p {
  16:     .BaseTextStyle;
  17: }

The trick here is made using a LESS feature. You can cross reference styles and have the referenced style copied into the secondary. Then, just because duplicated definitions in css are handled with a "last wins" rule, you can redefine some properties easily. This snippet produces the following CSS output:

   1: .BaseTextStyle {
   2:   font-family: Verdana;
   3:   color: #333333;
   4: }
   5: .AlertTextStyle {
   6:   font-family: Verdana;
   7:   color: #333333;
   8:   color: #ff0000;
   9: }
  10: p {
  11:   font-family: Verdana;
  12:   color: #333333;
  13: }

Note the duplicate definition in "AlertTextStyle". Since the "color" attribute is defined twice, the "#ff0000" wins over the previous. Also note that the default text is applied to "P" element with the same syntax.

Always create pages with styles

This article is really too short to completely describe the power of styles. However, I hope I gave you an idea of a good way to follow to create your next application. The benefit of organizing styles, both in HTML and in XAML are multiple, but the very first is to make them a common point to handle the application appearance, to easily accomodate your customer's requests.


Subscribe

Comments

No comments

Add Comment

Login to comment:
  *      *       

From this series