Cascading Style Sheets (CSS) are a powerful way to separate content from design in your Web Forms applications.

An effective use of CSS is an easy way to maintain and consolidate the visual aspects of Web development. Cascading Style Sheets are a Web standard that have been in existence for a number of years. Most modern browsers support CSS, so their use in your .NET applications should pose no cross-browser compatibility issues. However, like most things in the Web world, various browsers may behave differently depending on the CSS you feed it.

The practical use of CSS is the first step to creating and designing sites using Web CSS standards.

In this article, you will learn about the mechanics and the practical uses of CSS that you will find valuable as a .NET developer. This is your first step to creating and designing sites using Web CSS standards.

Structure, Design, and Behavior

In .NET, Web Forms are comprised of three elements: structure, design, and behavior. Isolating each element reduces coupling and increases maintainability and clarity in your code.

Structure

A Web Forms' structure is the actual HTML and WebControls markup of an ASPX page. As most programmers know, an HTML page must include certain elements and must include those elements in a certain order. This snippet shows an example of the structure of an HTML page.

<html>
  <head>
  </head>
  <body>
    <form>
      <p>
      </p>
    </form>
  </body>
</html>

This HTML markup must be structured as you see it. You could not put a <p> tag outside of the <body>, for example. Ideally, the only markups in your ASPX page at development time are HTML elements, user controls, and/or server controls.

Design

Traditionally, developers have embedded design and layout in the HTML/ASPX pages in the form of tables, font tags, and other hard-coded elements. Removing all visual layout, color, positioning, and other aesthetic control to the style sheet reduces your structure code and gives you a single point-of-contact to update your site.

An example might be, instead of doing this:

<td bgcolor="Blue">

You might simply use this:

<td>

Then, in the Style Sheet, you define <td> to be a certain color. If you wish to make a change across all your <td> tags, you only have to do so in one place.

Behavior

Often, Web Forms include some custom JavaScript. Instead of putting the JavaScript directly in the page, it is better to isolate the JavaScript into a separate file. This allows you to edit the file without redoing any ASPX pages, and also allows you to reuse that file on another page. This article does not address any JavaScript behavior.

Cascade Order

To effectively use Cascading Style Sheets, you must keep in mind how cascading works within the browser. You might liken cascading to object inheritance. When you define a style up the chain, lower-defined styles may override values of the base style. A Style Sheet's power is unleashed when you set up the right type of cascade.

Web Forms are comprised of three elements: structure, design, and behavior. Isolating each element reduces coupling and increases maintainability and clarity in your code.

Here is the order in which the styles are applied to elements on a page:

  1. Included files
  2. Head items (within the <style> tag)
  3. Inline styles

Included Files

Included files are when you reference an external style in the <head> tag using a <link> tag, as shown in this next snippet.

<head>
   <link rel="stylesheet"
         href="/Styles/global.css"
         type="text/css" />
</head>

Head Items

Head items are style definitions found in the <style> tag within the <title> tag, as shown in the next snippet.

<head>
   <style>
   h1
   {
      color:black;
   }
   </style>
</head>

Inline Styles

Inline styles are style definitions applied directly to an element via the style attribute. These are not recommended for use, as they are hard to maintain.

<h1 style="color:black;">Welcome</h1>

Application of Styles

You may apply styles to your document and elements in any of three ways: by element, by ID, or by class.

Element Styles

Often, you need to apply a style throughout your site to an existing HTML element. Perhaps you want all of your paragraphs to appear in the Arial font, have wide line spacing, and appear as black text. To style all the paragraphs on every page of your site without writing extra markup, associate the appropriate style to your paragraph tags (<p>). The next snippet shows what you put into your Style Sheet so you can link that Style Sheet to all your pages.

p
{
   font-family:Arial;
   line-height:1.5em;
   color:black;
}

Notice the beginning of this code block: the statement opens with the name of the HTML tag with no preceding characters. This is how you access elements within the HTML structure.

ID Styles

Every element in an HTML page may have an ID associated to it using the id attribute. An element ID is a unique identifier for each element on the page. The IDs allow technologies like CSS and .NET to distinctly locate an element on a page. Setting aside .NET development for a moment, element IDs are only required if you choose to create a style that is specific for a certain element. The next code snippet demonstrates how to apply a style to an element on the page using an ID.

<html>
  <head>
    <style>
    #divContainer
    {
    font-weight:bold;
    }
    </style>
  </head>
  <body>
    <div id="divContainer">Styled Container</div>
    <div>Unstyled Container</div>
  </body>
</html>

Notice the opening of this code block: the statement begins with a pound sign (#). The pound sign indicates to the browser that the following style is applied to an element on the page and is associated by its ID attribute value. Figure 1 shows the result of this HTML.

Figure 1: An ID style allows you to target a specific named control on a page.

Class Styles

Although a style applied to an element by ID is only available to one element on the page, class styles may be reused over and over again. Class styles may be defined and applied to like or disparate types of elements on the page. To illustrate how you might use a class style, create two containers on a page that hold other controls. Each container should show up 25 pixels away from the left border of the browser, as shown in Figure 2.

Figure 2: Use class styles to set a standard left indentation on controls.

The code to generate this Web page is shown in Listing 1.

As your site grows, split up your styles into multiple files.

Notice the opening of this code block. The statement begins with a period. The period or dot indicates to the browser that the following style is applied to an element on the page and is associated by its class attribute value.

Practical Applications

Now that you know how and when the styles are applied, it's important to understand why and where you should use each approach. When you create a site, the first visual aspect you want to affect is the font on each page. This type of application screams for the use of an Included File. This means that you create a global, or site-wide, Style Sheet file and include the file on each page in your application. Later, you may decide you want the background color on every page to be a light grey. To accomplish this, you use a new Element Style (body{background-color:#ccc;}) in your Included File.

As your site grows, certain pages develop specific layout requirements. As stated before, rather than sinking all of your style definitions into one unruly file, you'll find a best practice in spinning off a new Style Sheet file for pages that require heavy lifting. The next bit of code is an example of how to use two Included Files to achieve the granularity you need for complex layouts.

<head>
 <link rel="stylesheet" href="/Styles/global.css"
   type="text/css" />
 <link rel="stylesheet" href="default.aspx.css"
   type="text/css" />
</head>

This code loads in all global styles plus the definitions specific to the page.

Hierarchical Element Styles

An HTML document is organized around the Document Object Model (DOM). The DOM is a hierarchical object-based representation of your structured markup. Although the DOM is most often used in JavaScript, your awareness of the DOM construct helps you to write fewer classes and ID styles while empowering your Style Sheet definitions.

Perhaps your designer requires that all <h1> tags on a page show up with a solid border and all <h1> tags nested inside a content area display a solid border. In Figure 3, you can see an example of what that might look like.

Figure 3: Use global style sheets and <div> tags to create distinct areas on your page.

A couple of options are available to achieve the desired result. First, you could create a new class definition and apply this class to the <h1> tag, as shown in Listing 2.

The problem with the sample code shown in Listing 2 is that two changes are required to produce the desired result. One change is required in the Style Sheet and the other change is required in the HTML page. You can avoid these types of changes if you add enough hooks.

Hooks are a combination of HTML elements with their associated class or ID attribute values. The art of coding an HTML page is in knowing where to place the appropriate element and class/ID definition. A mature structure to your page allows you to hook into your page from your Style Sheet without always requiring new class or ID definitions.

Listing 3 shows a revised example of styling the navigational header without having to add a new class definition.

In this version of the code, you use the power of cascading styles. Instead of creating a new tag, you write code saying that anywhere an <h1> tag shows up within a container that has a class of nav, apply this style. This allows you to define a good hierarchical structure that you can duplicate from page to page, and thus be able to make changes across all pages without changing structure or names of elements.

The Box Model

Containment and positioning within a Style Sheet are controlled by the Box Model. The Box Model is the metaphor for how positioning, margins, padding, and borders are applied to an element, as shown in Figure 4.

Figure 4: The Box Model has four parts.
  • Margin. The margin is the space between the container element and any other surrounding elements.
  • Border. The space on the edge of the container element
  • Padding. The space between the border and any content in the container element
  • Content. The area where your text, controls, etc., will appear

Resources

For an in-depth tutorial. please see: http://www.brainjar.com/css/positioning/default.asp.

Page Layout

You can use the Box Model as a guide to lay out elements on a page. In this section, you will lay out an input form page using only CSS for positioning and design. In the past, you may have used a <table> to lay out pages with a certain look and feel. You will now use CSS to accomplish the same thing.

Awareness of the DOM (Document Object Model) helps you to write fewer Style Sheet entries.

The input form you create is standard in almost any development effort. The form asks for a user's name and e-mail address. Figure 5 shows the finished page.

Figure 5: Use CSS to lay out a page instead of a <table> tag.

Step 1

To begin, you must first learn the semantics of the HTML that create the structure of this simple input page. Listing 4 shows how to use <div> tags to create the basic layout. You can see the results in Figure 6.

Figure 6: This is a simple screen layout using <div> tags.

Looking at the code, you might notice that the <div> tag replacement seems to be a one-for-one switch where you may previously have had <table>, <tr>, and <td> tags.

Switching the tags from <table> to <div> lets you design a number of benefits. This technique unleashes the power of your Style Sheet and gives you full control of the placement of the elements in relationship to each other. Notice the different placement of labels in the screen shot from the un-styled document to the final product shown in Figure 5. The design benefits when you can put the labels anyplace on the page. Additionally, the page is now a standards-based form which will render appropriately in many devices (Example: WAP, handheld, etc.) and not just a computer's Web browser.

Step 2

Now that you have the basic structure, you can move on to marking up your HTML with the right hooks. Listing 5 shows the updated hooks you can employ to get a better rendering of this page.

Listing 6 shows the appropriate Style Sheet entries that must be made to accomplish the final look and feel.

Figure 7 shows the result of adding the appropriate styles. You can see that now the labels and the text boxes are on the same line.

Figure7: Simple changes in the Style Sheets can have a big impact on the page layout.

HTML Explained

So what changed? All the styling necessary for this layout is controlled by classes exclusively. Remember: the value of a class is to define a few styles and use them over and over again.

Here is a description of changes one section at a time:

<div class="inputForm">
...
</div>

The markup now features a class of inputForm to the main container <div>. Denoting this container with this class allows you to gain exclusive access to the elements inside any form that uses the inputForm class. Like this:

<div class="section">
   <div class="lbl">Name</div>
   <div class="ctl"><asp:textbox id="txtName"
      runat="server" /></div>
</div>

The next segment includes a class called section. The section class defines what is contained in a single section or row in the parlance of a table layout. The section class gives you the granularity to affect a pair of labels and a control at the same time.

Next, a class named lbl is added. The lbl or label class allows the Style Sheet to affect the container that acts as the label for your input box.

Finally, the class ctl is added to grant access to the input control in the form. This pattern is repeated throughout the form for each section of label and control pair. The only deviation to the pattern is in the button section.

<div class="section">
   <div class="lblNoText"></div>
   <div class="ctl"><asp:button id="btnSend"
      text="Send" runat="server" /></div>
</div>

Often, pages are not designed to have a label next to the command buttons. This requirement gives rise to an alternate class, lblNoText, which excludes any styles not relevant to the label area of this section.

CSS Explained

The first item in your Style Sheet is the style definition for the inputForm class.

.inputForm
{
   position:relative;
}

This definition only has one entry: the Style Sheet sets the position of this element to relative. There are two common positioning types: relative and absolute. Relative positioning stacks elements next to each other in a chain as they appear in the HMTL document. Absolutely positioned elements are placed on the page according to the provided left and top settings defined in the style sheet. The absolute position is applied regardless of how the element structurally appears in the HTML document.

Next, style the sections:

.inputForm .section
{
   position:relative;
   clear:both;
}

Notice that the definition begins with the inputForm class. This uses Hierarchical Styles to narrow down exactly which section is affected on the page. If you have another element on the page using a class of section, you are assured that only the elements within inputForm receive the new style.

Validating your Style Sheets highlights possible problems in various browsers.

The next new concept in this sample is the style of clear:both. To fully understand what the clear style does, you must first understand how a float works. When you relatively position an element on your page, the default behavior of any adjacent element is to display directly under the preceding element. When you apply the float style, you allow adjacent elements to appear next to your preceding container.

Should you choose to break the chain of floating elements, you may apply the clear style to create a break in the float and resume display of an element under the preceding element. Basically, the clear:both style guarantees that the sections will appear one underneath the other. Now examine the style for the individual elements in the section.

.inputForm .section .lbl,
.inputForm .section .lblNoText
{
   position:relative;
   float:left;
}

Noteworthy about this segment is the listing of separate definitions that share a single style. When you encounter instances where grouping definitions together makes sense, all you have to do is separate your definitions by a comma, and the resulting style applies to all definitions in the list. Finally, look at the style for the control area.

.inputForm .section .ctl
{
   position:relative;
   float:left;
}

The section above does not introduce any new concepts, but acts as a stub for some additional styles applied in the next section.

Step 3

To give your form some final flair, the following changes update the look of the page by controlling the Style Sheet exclusively. Please note that this section does not feature any changes to the HTML. In fact, now that the page has the appropriate hooks, an entirely different layout is applied with bold colors for this page. (See the accompanying download files for some examples.) Listing 7 shows some changes made to the Style Sheet that give the finished look, as shown in Figure 5.

The first addition to the Style Sheet is to the body of the page.

body
{
   font-family:Tahoma,Verdana,Arial,Helvetica,
      sans-serif;
}

This allows all text on the page to display in the Tahoma font. The list of fonts gives a cascading list of fonts that you look for if the supported font is not found. For instance, if this page is served to a Macintosh computer and the Microsoft fonts of Tahoma and Verdana are not installed, the page displays the text in Arial or Helvetica. If no match is found, the browser uses the system-defined sans-serif font, whatever that may be on that particular computer. No new styles were added to the section class, so you may now move to the label areas.

.inputForm .section .lbl,
.inputForm .section .lblNoText
{
   position:relative;
   float:left;
   width:100px;
   font-weight:bold;
   margin-right:10px;
   padding:3px;
}

The new items should prove self explanatory. If you don't recognize the margin or padding, please refer to The Box Model section (above) for details. Next, add some color to the labels on the form.

.inputForm .section .lbl
{
   background-color:#ccc;
      /* Web safe color hex value for grey */
}

Remember that in the previous code segment, some general settings were applied to the lbl and lblNoText. Grouping these definitions together guarantees that they will have the same general styles. The desired design only calls for the labels with text in them to have a background color. Therefore, this definition only applies to the lbl container. Finally, the styles for the control section allow the container to line up uniformly with the label container.

.inputForm .section .ctl
{
   position:relative;
   float:left;
   width:200px;
   padding:2px;
}

The width style gives the horizontal boundary of the container and applies the padding in order to match the label.

Working in Visual Studio .NET 2003

Visual Studio .NET is a great development tool for coding in your favorite .NET language. However, the HTML and CSS support is not exactly the best. Here is a short list of drawbacks in relying on the Visual Studio .NET designer for CSS support.

  • Limited Design Time Support. Design time support for CSS in the design pane of an ASPX page is only applied to the page once, when a Style Sheet is dragged onto the page as you open the document. Any subsequent changes to the Style Sheet are not reflected in real-time back to the design window. You may see the changes if you choose View and then Refresh in Visual Studio .NET.
  • Invalid Markup. If you apply a style to a Web control from the Style drop-down menu, Visual Studio .NET applies a class attribute to the control. This does not wire-up correctly when the control is rendered to the browser, as the appropriate attribute for the server control is cssclass.

The news is not all bad! Visual Studio's style editor is available to you within the editor window of .CSS files and is quite impressive. The dialog box (Figure 8), available through the Build Style button in the Style Sheet toolbar, is rich in settings and visual aids.

Figure 8: The Style Builder dialog box is excellent for building your styles.

The Practical Answer

You will find success in using the Build Styles dialog box to create your styles and then switching to the HTML pane of your ASPX file to associate your styles by hand or using the Document Outline pane in conjunction with the Formatting Toolbar's Style Sheet drop-down list. To see your changes, select View and then Refresh, and Visual Studio .NET reloads your style definitions.

Best Practices

As with all techniques, there is a difference between applying the rules and learning the craft. The following tips will guide you through some proven best practices in coding Cascading Style Sheets.

Use Hungarian Notation for Element IDs

Hungarian notation in your IDs greatly eases the maintainability of your Style Sheets as you know what the element type is by looking at its ID.

Use Multiple External Style Sheet Files

Set up a Style Sheet for your entire application and include this file on each page in the site, but don't nest all of your styles in one file. Defining all of your styles in a single file is a recipe for a monster to maintain and to unnecessarily push unused style definitions to the client. If your styles are site-wide, include them in the global definition file; otherwise create a Style Sheet for areas of your site and even individual pages.

Use a Common File Naming Standard

To associate your Style Sheet files together, use a file naming standard. One concept that proves successful is to name your Style Sheet files with the name of your ASPX file name plus the extension of .css. For example, if your ASPX file is default.aspx and you wish to have a custom CSS file for this page, the name is default.aspx.css. This makes your life easy in coding the files, as you can always figure out what your file name is and the files show up right next to each other in Visual Studio's Solution Explorer.

Use ID Styles as a Last Resort

ID styles are powerful, useful, and necessary, but only use them when you must. Styles applied to an ID are the definitions explicit and exclusive to the element to which the style is associated. This limits your ability to reuse your styles. Try to format your page with as many hierarchical element styles and classes as possible and you will notice that as you add elements to your page, less and less work is required to get the look and feel you want. Styles tied to IDs should be defined only when you have a style definition that is only appropriate to the element in question.

Name Against Function, Not Placement

Try to name your element IDs and classes against the function of the element, not the placement. For instance, if you create an ID of divFooter on your page and then your user asks for the content in the footer to show up on the right-hand side of the page, your ID no longer makes sense. Look for ways to name your elements and classes with terms like ContentPrimary, Content Secondary, Navigation, and Links.

Avoid Using Head and Inline Styles

Using Head and Inline style wire-up techniques flattens your presentational layer architecture and co-mingles your structure and design. CSS definitions are best kept in their own file outside the ASPX file. Another reason to keep separate files is that Visual Studio .NET 2003 only supports IntelliSense in CSS files.

Avoid Unnecessary Debugging Sessions

As CSS is purely a client-side technology, there is no reason for you to launch a debug session in order to check your changes. If your keyboard is set up with the default settings in Visual Studio, you may simply press CTRL F5 to launch the application once and then click the Refresh button to see any changes.

Validate Your Code

Before you go live with a Style Sheet, take a moment to validate it against the official CSS validator: http://jigsaw.w3.org/css-validator/validator-uri.html. This identifies any potential problems with your styles that may cause issues with various browsers.

Summary

The use of Cascading Style Sheets assists in the maintainability of your sites. Taking advantage of global styles, page-styles, and the hierarchical nature of style sheets allows you to create a site that can be modified quickly and easily. Although there are some challenges in learning how to take advantage of these styles, taking the time is well worth the effort.