Windows DevCenter    
 Published on Windows DevCenter (http://www.windowsdevcenter.com/)
 See this if you're having trouble printing code examples


Why Do ASP.NET Programmers Need to Learn CSS?

by Dan Hurwitz and Jesse Liberty
05/01/2007

ASP.NET and the HTML it generates is all about specifying the elements on a web page, but historically, ASP.NET has not been great at controlling the layout or even the subtleties of the display of those elements. What we need, of course, is a straightforward way to preserve the structural details that ASP.NET controls provide while gaining precise control over presentation. The answer is Cascading Style Sheets, and this article will argue that ASP.NET programmers who embrace CSS as their own, rather than thinking of it as an esoteric skill of designers, place themselves ahead of the pack.

The Internet was originally invented by academic types (with government support) as an easy and efficient way to exchange scientific research. Content was king; format and presentation were afterthoughts. HTML (HyperText Markup Language) was created by Tim Berners-Lee to facilitate this goal.

Early HTML was all content and structure. The browser supplied all the formatting. For example, consider the small HTML file, Sample.htm, shown in Example 1.

Example 1. Sample.htm

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<pre><code>
<html>
    <head>
        <title>Sample HTML</title>
    </head>
    <body>
        <h1>Page Heading</h1>
        <h2>First Section Heading</h2>

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.

        <h2>Second Section Heading</h2>
    <h3>Unordered List</h3>
    <ul id="list1">
        <li>One</li>
        <li>Two</li>
        <li>Three</li>
        <li>Four</li>
    </ul>
    <h3>Ordered List</h3>
    <ol id="list1">
        <li>One</li>
        <li>Two</li>
        <li>Three</li>
        <li>Four</li>
    </ol>

Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

    </body>
</html>

The page in Example 1 consists of a title, a major heading, two minor headings, some text under each minor heading, and two lists, and it will display as shown in Figure 1 when rendered by Internet Explorer 6 (IE6). A simple page like this will look essentially identical in most browsers, but more complex HTML may look significantly different depending on whether it's running in Internet Explorer, Safari, Firefox, or any of the many available browsers for mobile devices.

Sample HTML
Figure 1. Sample HTML rendered in IE6

The HTML of Example 1 says nothing about how the page it defines is to be displayed. It doesn't specify the font, type size, color, or spacing of any of the elements. The browser controls all of that. Ultimately, the browser decides how the page will look. The author of the page must trust the browser to display the page properly. Or not, as you will see momentarily. But the structure of the page is well specified by the HTML. There is a top-level heading element, <h1>, which contains content that will always, unambiguously, be treated as a top-level heading.

This is a good thing, for many reasons. It means that search engines instructed to look only in page headings will find the page. Page readers, used by the visually impaired, will know to identify this content as a major heading, not body text. But the most important reason to use HTML structure is so that you can globally control the look of all the pages in the web site.

IE displays the top-level heading using a large, bold Times New Roman font or some similar typeface. You could replace the <h1> with the following HTML to get nearly the same effect:

<b><font size=6 color=black face="Times New Roman, Serif">
    Manual Page Heading
</font></b>

You may get away with this for an element typically used only once on a page, but even there, it is very difficult to make sure all the pages in your web site have the same appearance. Also, the font attribute used in this snippet has been deprecated by the W3C, meaning that a page that works fine in today's browser may no longer work correctly in a future browser. So using the predefined structural elements provided by HTML is a good thing.

But leaving the presentation up to the browser sacrifices a level of control that few developers (and no designers) are willing to put up with. And it is boring.

The way to regain control and to spice up your page is with styles.

What Are Styles?

One of my favorite columnists is the Style Man in Bicycling magazine, who, if asked "What is style?", would no doubt reply that if you have to ask, you are probably hopelessly lost style-wise. However, in the world of web development, it is a very reasonable question.

When it comes to web applications, style refers to the appearance of your content. In a perfect world, HTML describes what you want to display (the word "Danger"), and styles describe how to display it (big, bold, and red).

Web applications use styles to ensure attractive and reasonable display on a wide variety of devices, including desktop and laptop computers, tablet PCs, mobile PCs, telephones, PDAs, televisions, printers, audio devices, and media not yet imagined.

Style is an overloaded word. We use it to mean the general look and feel of part of a page, but it is also a keyword used to indicate specific rendering information to the browser. In that sense of the term, a style attribute specifies how an object will be rendered to an output device, typically a browser. Styles are used to manipulate the layout and appearance of controls and text, detailing every aspect of the appearance from border color to font size.

There are many different styles available. There are style attributes for font family, font style (normal, italic, oblique, etc.), size, weight, and decoration (underline, overline, line-through, or blink). You can set the foreground and background colors of page elements, create borders around elements, and specify the amount of blank space that surrounds items. You create space with padding, either as a percentage of the overall size or as a value measured in pixels, inches, centimeters, points, ems, or one of several other somewhat obscure units. And on and on.

Suppose you don't like the default way the <h2> headings look. In HTML, you can add style attributes directly to the <h2> element to control the way the browser renders it. So for example, you could add the highlighted attributes from the following snippet to the default <h2> to make the heading display in an Arial Black font family, xx-large, with maroon text over an aqua background.

<h2 style="font-family:Arial Black; font-size:xx-large; 
            background-color:Aqua; color:Maroon">
    First Section Heading
</h2>

This results in the section heading shown in Figure 2.

H2Modified
Figure 2. Results of adding style attributes to an <h2> element

The big problem with this sort of implementation is that you must add the exact same attributes to every element that should have the same appearance. Also, you must specify the style for every element essentially from scratch. There is an easier way: Cascading Style Sheets (CSS).

Before getting into the nitty-gritty of CSS, there are a few basics to cover.

In all the HTML shown so far, style attributes were added to the HTML tags. Obviously, as ASP.NET programmers, we primarily use ASP.NET controls, and do relatively little direct HTML coding (remembering, of course, that ultimately, all ASP.NET controls are rendered on the browser as HTML). As we will talk about at the end of this article, with CSS replacing HTML tables for layout, we will likely be using even less direct HTML in the future.

ASP.NET controls provide many properties that are exactly analogous to the HTML style attributes, although implemented in a more logical and consistent way. These are rendered to the browser as in-line styles of normal HTML elements (see below), but Visual Studio (and Visual Web Developer) provide a very easy and object-oriented way to deal with them, and they are well supported by IntelliSense.

For example, the Label control shown in Design view of Visual Studio 2005 in Figure 3 will display the same as the <h2> from the previous code snippet.

LabelInDesignView2
Figure 3. Label in Design view made to look like the previous <h2>

There are three different levels at which styles can be applied:

Inline Styles

You can apply styles to a specific HTML element using an inline style attribute, as in the following:


<input type="text" value="Sample text" style="color:Red;font-family:Arial;
        font-weight:bold;width:150px;" />

The style attribute contains one or more style properties, each consisting of a property name and value separated with a colon. Each property-value pair is separated from the next with a semicolon.

Inline style attributes are set for ASP.NET controls using properties of the controls, either declaratively in the markup file, or using the Properties window in Design view. To see this, create a new web site in Visual Studio or Visual Web Developer (VS/VWD). Call it AspNetInlineStyles.

In Design view, drag a Label and a Button control from the Standard section of the Toolbox onto the page. In the Properties window, set the properties displayed in Table 1.

Table 1. Properties to set in the Properties window

Control Property Value
Label1 Font-Bold True
Font-Name Arial
ForeColor Red
Text Sample Text
Width 150px
Button1 Font-Bold True
Font-Name Arial Narrow
BackColor Yellow
Text Toggle Colors
Width 150px

Once you've entered the values in the table, your property should look something like the one shown in Figure 4. When you set the Font-Name property, VS/VWD automatically fills in the Names property for you.

InLineDesignView
Figure 4. ASP.NET controls in Design view showing style properties

Run the application. When the page comes up in the browser, view the rendered source by clicking on the View->Source menu item (in IE).

Notice how the ASP.NET Label and Button controls are rendered to the page in HTML:

<span id="Label1" style="display:inline-block;color:Red;
    font-family:Arial;font-weight:bold;width:150px;">Sample Text</span>
<input type="submit" name="Button1" value="Toggle Color" id="Button1" 
    style="background-color:Yellow;font-family:Arial Narrow;
    font-weight:bold;width:150px;" />

The result is exactly the same as if you had handcoded HTML using inline styles. In fact, when ASP.NET renders a page to the browser, all the ASP.NET controls are converted to straight HTML output with elements and their attributes set to appropriate values. Label controls are rendered as <span> elements, and Buttons are rendered as <input> elements of type submit.

You can also set or change style properties (or any properties of a control, for that matter) programmatically. Our button says Toggle Colors, so obviously we want it to act on the ForeColor property of the Label control.

To see this, double-click on the Button control in the Design view to open up the event handler in the code-behind file for the Click event. Enter the highlighted code from Example 2.

Example 2. Button Click event handler to toggle the Label color

protected void Button1_Click(object sender, EventArgs e)
{
    if (Label1.ForeColor == System.Drawing.Color.Red)
    {
        Label1.ForeColor = System.Drawing.Color.Green;
    }
    else
    {
        Label1.ForeColor = System.Drawing.Color.Red;
    }
}

Again run the application. Every time you click the button, the ForeColor property of the Label will toggle between red and green.

Pros and Cons

Inline properties are excellent for overriding the styles in your external style sheet for a particular control. Unfortunately, they are very easy to use and developers are often seduced into using them to excess, creating markup that is very difficult to maintain.

Document-Level Styles

You can set all the styles for a single HTML page at the top of that page, but this is rarely done in practice and can be hard to maintain, so we will pass over this approach in favor of extensive coverage of the preferred approach: external or cascading style sheets.

The one thing to note about document-level styles is that if you do create styles at the document level, these styles will take precedence over styles created in your cascading style sheets, as noted below.

External Style Sheets

External style sheets are called cascading style sheets because the style specifications cascade down from the most general (the external style sheet) to the more specific (the document-level styles) to the most specific (a style applied to a particular element).

If your style sheet says that text boxes should have a white background, but one particular page says that its text boxes will have gray backgrounds, and on that page the seventh text box has its own style calling for a yellow background, the rules will cascade as you would expect: all the other pages will have text boxes whose background color is white. Our one document will have text boxes with gray backgrounds except for the seventh text box, which will be… you guessed it! Yellow.

For a complete discussion of CSS, see HTML & XHTML: The Definitive Guide, 6th Edition, by Chuck Musciano and Bill Kennedy, or CSS: The Definitive Guide, 3rd Edition, by Eric Meyer, both published by O'Reilly.

In general, the most powerful and easiest to maintain way to apply styles to a web site is with an external cascading style sheet (sometimes just called a style sheet), with an extension of .css. This external style sheet is imported into the page using an HTML <style> element, as shown in  the following snippet:

<head runat="server">
    <style type="text/css">@import url(MyStyleSheet.css);</style>
    <title>My Home Page</title>
</head>

You are not limited to a single style sheet. In fact, you are free to create separate style sheets for different sections of your web site, for example, or for rendering to different devices.

External Style Sheet = Style Sheet = Cascading Style Sheet. All three of these terms refer to the same thing, a file that contains styles that will be "included" into one or more HTML files.

To see a cascading style sheet in action, create a new web site called AspNetStyleSheet. Click on the Website-> Add New Item... menu item and add a Style Sheet. You could use the default name of StyleSheet.css, since we will only be using a single style sheet in this web site, but let's call it CorporateStyleSheet.css.

The default style sheet template looks like the following, with an empty selector for the body element:

body {
}

A selector will affect any element of the named type. For example, if you put <h1> into your style sheet, the styles you attach to that selector will affect every h1 element.

To see this, add the following line to CorporateStyleSheet.css:

h1 {color:red;font-style:italic;font-weight:bold;}

Most of the styles in a style sheet will be declared as style classes, defined with a leading period. A style class is applied to an HTML control using the class attribute.

Style classes are applied to ASP.NET controls using the CssClass attribute, as in the following:

<asp:TextBox ID="txtName" Cssclass="GreenText" runat="server" />
The names used for style classes are case sensitive. If you try assigning the class name greentext to a property of an object in this web site, it will be ignored. There will be no error message.

Example 3 contains the complete contents of MyStyleSheet.css, including both the selectors and the style classes you will use in the example.

Example 3. CorporateStyleSheet.css containing both selectors and style classes

body {
}
h1 {color: red; font-style:italic; font-weight:bold;}
.MyHeading2
{
    font-family:Arial Black, Sans-Serif;
    font-style:normal;
    font-weight:bold;
    font-size:x-large;
    background-color:Aqua;
    color:Blue;
    padding-left:.1in;
    padding-right:.1in;
    line-height:.75in;    
}
.MyHeading3
{
    font-family:Arial Black, Sans-Serif;
    font-style:normal;
    font-weight:bold;
    font-size:large;
    text-decoration:underline;
    color:Black;
}
.BodyText
{
    font-family:Times New Roman, Serif;
    font-style:normal;
    font-weight:bolder;
    font-size:medium;
    color:blue;
}
.WarningText
{
    font-family:Times New Roman, Serif;
    font-style:normal;
    font-weight:bolder;
    font-size:medium;
    color:red;
}

For attributes requiring a length, such as padding and line-height, allowable units are listed in Table 2. Relative units are relative to the other content on the page.

Table 2. Style length units

Unit Abbreviation Type
Width of lowercase M em Relative
Height of letter x ex Relative
Pixels px Absolute
Inches in Absolute
Centimeters cm Absolute
Millimeters mm Absolute
Points (1/72 inch) pt Absolute
Picas (12 points, or 1/6 inch) pc Absolute
Percentage % Percentage

Also, any length property can be prepended with either a plus (+) or minus(-) sign to indicate that the value is to be added or subtracted, respectively, from the current value of the property.

Percentage units are defined for each different property. Depending on the type of control, it might be relative to the element's font size, or perhaps the total space available to the element.

While in Source view for the page, add the following <h1> to demonstrate how your h1 selector works.

<h1> Heading 1</h1>

Next, follow these steps:

  1. Switch to Design view. Type some text on the page.
  2. Then drag a Label control onto the page. Set the Text property to Heading 2 and the CssClass property to MyHeading2. Type some text on the page.
  3. Drag a second Label on the page. Set the Text property to Heading 3 and the CssClass property to MyHeading3. Type some text on the page.
  4. Add two more Label controls with the CssClass set to MyHeading2 and MyHeading3, along with some text.
  5. To format the text under the two MyHeading3 headings, switch to Source view and insert some <div> or <span> elements so that you can apply the BodyText style.
  6. Finally, add one more <div> element with the class attribute set to TextWarning.

The Design view should look something like Figure 5.

ExternalStylesInDesignView
Figure 5. AspNetStyleSheet in design view

The Source view will look something like Example 4, except the highlighted line of code will not yet be present--you must add it manually.

You saw this line previously in a code snippet; it imports the style sheet. It uses the @import command to import the style sheet specified in the URL. In this case, a relative URL is provided and refers to our style sheet in the current directory. Since it is a URL, it can be either relative or absolute. For example, you could provide an absolute URL such as http://CorporateWebSite.com/stylesheets/handhelds.css.

The @import command must appear in the <head> element, and before any conventional style rules are specified. Otherwise, the imported style sheet will be ignored. This allows the browser to properly cascade styles from the external style sheet down to the document-level styles.

Example 4. Default.apx for AspNetStyleSheet

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title>ASP.NET Style Sheets</title>
    <style type="text/css">@import url(CorporateStyleSheet.css);</style>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <h1> Heading 1</h1>
        This is some text.
        <br />
        <asp:Label ID="Label2" runat="server" CssClass="MyHeading2" 
            Text="Heading 2"></asp:Label>
        <br />
        Some more text.
        <br />
        <asp:Label ID="Label3" runat="server" CssClass="MyHeading3" 
            Text="Heading 3"></asp:Label>
        <div class="BodyText">
            Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do 
            eiusmod tempor incididunt ut labore et dolore magna aliqua.
        </div>
        <asp:Label ID="Label4" runat="server" CssClass="MyHeading2" 
            Text="Another Heading 2"></asp:Label>
        <br />
        <asp:Label ID="Label5" runat="server" CssClass="MyHeading3" 
            Text="Another Heading 3"></asp:Label>
        <br />
        <span class="BodyText">
            Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris
            nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in 
            reprehenderit in voluptate velit esse cillum dolore eu fugiat 
            nulla pariatur.
        </span>
        <div class="WarningText">Warning: Viewing raw or undercooked web pages can 
                    be harmful to your cosmic karma.
        </div>
    </div>
    </form>
</body>
</html>

The resulting page is shown in Figure 6.

ExternalStyles
Figure 6. External styles in action

Layout with Style Sheets

This article has focused exclusively on using style sheets to apply styles to specific elements on the page. Many web page developers use HTML tables to control the layout (or positioning) of their controls on the page. This is because using inline absolute positioning is ugly and very difficult to maintain.

Using HTML tables for layout is relatively straightforward and very easy for most people to visualize and implement. The problem is that to get precise layout, you often have to embed tables within tables, and soon the HTML becomes confusing and difficult to maintain. Also, and perhaps more crucially, using tables for layout can produce maintenance nightmares, especially if you need to change the layout on a large site with many, many pages. (Note also that there is a bit of a performance penalty on pages with deeply nested tables, but as the Internet gets faster thanks to DSL and FIOS, this is less of an issue.)

To address these concerns, CSS comes galloping to the rescue, or so many web developers would have you believe. There is not space in this article to do justice to using CSS for layout, so we will tackle this issue in a future article. In the meantime, for a taste of what can be accomplished using CSS, we recommend a relaxing visit to the CSS Zen Garden website.

Dan Hurwitz is the president of Sterling Solutions, Inc., where for nearly two decades he has been providing contract programming and database development to a wide variety of clients.

Jesse Liberty is a senior program manager for Microsoft Silverlight where he is responsible for the creation of tutorials, videos and other content to facilitate the learning and use of Silverlight. Jesse is well known in the industry in part because of his many bestselling books, including O'Reilly Media's Programming .NET 3.5, Programming C# 3.0, Learning ASP.NET with AJAX and the soon to be published Programming Silverlight.


Return to Windows DevCenter.

Copyright © 2009 O'Reilly Media, Inc.