Gilsbach Designs - Web Site and Graphics Design austin texas

Gilsbach Designs Home

Introduction to Cascading Style Sheets (CSS)

By Mike Gilsbach, Gilsbach Designs

Anyone who has worked with HTML knows that almost any element in a web page has a tag associated with it (<TABLE> for a table, <P> for a paragraph, <UL> for an unordered list, etc).  Further, there are often optional attributes that can be specified for a given tag to control the way the element is displayed (color, size, etc.)  There are two problems with this model, however.

First, these attributes are somewhat limiting.  For example, you can specify that a table is to have a border attribute of "1" (<TABLE border="1">), but the actual display and characteristics of that border are largely left at the mercy of the browser displaying it.  With this setting you will usually get the rather bland beveled border.  In Internet Explorer, for example, it would look like this:

Intro to CSS - Example 1

You don't really have any control over the color or appearance of the border and the border will appear around the entire outside of the table and around the edges of every table cell.  This may or may not be what you want, but the HTML attributes don't give you any real control over it.  As we will see, style settings resolve this problem by giving you considerably more control over the display of an element than you would have with simple HTML tag attributes.

Second, when you specify an HTML tag attribute, it only applies to the one element that you specified it for. The border attribute that you specify for a table, for example, is only applied to that table and no others. This is fine if you only have one table or if the display characteristics of the table are unique. But what if you have ten tables, all of which have the same border characteristics. Or worse, what if you have ten pages, each with ten tables. That's one hundred separate border specifications. Aside from the redundant specifications, this can be a hassle when you decide to change the specification. You have to change all one hundred specifications. Style sheets resolve this problem by allowing you to specify display attributes for multiple common elements in one location.

This article is intended to provide you with a basic understanding of how Cascading Style Sheets work and provide some insight into how useful they can be. While we will examine some of the more common style settings, we will certainly not cover every aspect of CSS or every possible attribute. In fact, we won't even touch on one of the more intriguing uses of CSS which is Dynamic HTML (basically, using JavaScript to dynamically modify CSS settings). For more on all of this, please see the links to additional resources at the end of the article.

You should note that CSS is a client-side technology and as such is subject to the often irritating vagaries of browser differences. Not every CSS element will work the same way, or at all for that matter, in every browser or every version of browser. I have tried to limit this discussion to those elements which will work the same in relatively recent versions of Internet Explorer and Netscape Navigator. For more details on which elements are supported in which browsers, please see the links at the end of the article.

Levels of Style Settings

Before we discuss the actual syntax of style settings, you should understand that there are three levels at which the settings may be applied - Local, Global, and Cascading.

  • Local: Local, or inline, style settings are only applied to the single occurrence of the element for which they are specified. A local style setting on a table, for example, will only be applied to that table and no other. In this respect they are not much different from HTML tag attributes. To return to our example of ten pages with ten tables each, we would still need one hundred Local settings. However, Local settings are still useful in that they can give you better control over the appearance of the element.

    Local style settings are specified in the style attribute of an element's tag. For example, the following sets the background color of the table to blue and indents it from the left side of the page by 25 pixels:

    <TABLE style="background-color:#0000FF; margin-left:25px">
  • Global: Global, or document-level, style settings are applied to all similar elements within a single web page. This is better than Local settings in that we can control all of the similar elements for a page with one setting. Instead of one hundred settings for our ten pages, we have ten Global settings - one for each page.

    These settings are placed in a STYLE tag within the header of the document. For example, the following settings would be applied to all tables in the page:

    <HEAD>
    ...
    <STYLE>
       TABLE{background-color:#0000FF; margin-left:25px}
    </STYLE>
    </HEAD>
    ...
  • Cascading: This is where CSS really gets useful. Cascading settings are similar to Global settings except that instead of being placed in a STYLE tag, they are placed in an external text file, or style sheet. The settings are applied to any similar elements in any page that references that style sheet. In this way, any changes made in the style sheet "cascade" down to all of the pages that reference it. With an external style sheet, we only need one setting for all 100 tables on all 10 pages. Now that's efficient!

    The style setting itself would be stored in an external text file, usually with the extension ".css". For example, the style sheet could be called "table_style.css" and would contain the following:

    TABLE{background-color:#0000FF; margin-left:25px}
    Note that this is the same as the contents of the STYLE tag in the Global setting above. The syntax is the same.

    Now we just need to tell each of the ten pages how to reference this style sheet. This is done using a LINK tag in the header like the following:

    <HEAD>
    ...
    <LINK rel="stylesheet" type="text/css" href="table_style.css">
    </HEAD>
    ...
    Note the href attribute. This specifies the location of the external style sheet. In the example above, we assume that the sheet is in the same directory as the web page. You may wish to specify an absolute path such as "http://www.yoursite.com/table_style.css". This way you can copy this link tag into any page on your site, regardless of which directory it might be in.

Style Hierarchy

Since it is possible to specify settings at multiple levels, what happens when the settings conflict? That's quite simple. The closer the setting is to the element, the higher the precedence. In other words, Local settings take precedence over Global and Cascading settings and Global settings take precedence over Cascading settings. So, for example, if you have a font color setting for table cells at the Local level, that setting will be applied to that cell regardless of any font color settings for table cells at the Global or Cascading level. 

However, the hierarchy only comes into effect when the settings conflict. It is possible, and sometimes useful, to have settings for the same element at multiple levels. For example, you could set the font face for table cells in an external style sheet, set the font color for table cells in a Global setting for one page, and set the background color of one table cell in that page with a Local setting. In such a case, all three settings would be applied to that table cell because the settings don't conflict. 

This can be very useful as it allows you to make distinctions between style settings that are universal to your site and settings that are specific to the content of a page or part of a page. 

Style Syntax

The syntax for style settings is relatively simple. There are three items that you need to specify for any style setting: the selector, the property, and the value. The selector specifies which element we want to apply the setting to (a table, a list, etc). The property specifies what display aspect we want to modify (color, size, etc). The value specifies the setting we want for the property (blue, 10pt, etc).

The basic syntax for Global and Cascading style settings looks like this:

selector{property:value; property2:value; property3:value value2 value3}
There are several things to note here:
  • The selector is followed by the property/value pairs enclosed in curly braces ( { } ). 
     
  • Property/Value pairs consist of the property, then a colon (:), then a list of one or more values for that property.
     
  • You may specify any number of property/value pairs for a single selector, but they must be separated by a semicolon (;).
     
  • You may specify multiple values for one property, in which case you separate the values by a space.
     
  • Property names and value specifications are not case sensitive.

For Local style settings, the property/value pair syntax is the same, but you don't need the selector because the setting is already enclosed in the style attribute of the tag that it applies to. That syntax looks like this:

<TAG_NAME style="property:value; property2:value; property3:value value2 value3">
Let's review some examples.

The following is an example of a Local style being applied to one table.

<TABLE style="background-color:#74A9F8; font-family:arial; font-size:12pt; border:1px solid #000000">
...
This is a Local style, so we use the style attribute. The first property/value pair sets the background color of the table to a specific shade of blue with a hexadecimal value (color settings in CSS may use the hexadecimal value or a color name like "blue" if you don't feel like being too specific). The second and third pairs set the font face and size, thus eliminating the need for any FONT tags in the table. Notice that the property for setting the font face in CSS is "font-family". Also note that the value for the font size is set in points (12pt). 12 point font is comparable to setting the size attribute of the FONT tag to 3. The final pair includes multiple values for one property. We set three different values for the border property - a width of 1 pixel ("px" is the abbreviation for pixels in all CSS settings), we specify that the border is to be a solid line and we specify the color of the border (black) in hexadecimal format.

This is what the table looks like in Internet Explorer:

Intro to CSS - Example 2

Notice that this is a two cell table, but the border does not appear between the two cells. This is because we specified the border property on the TABLE tag, not on the TD (cell) tags. This distinction can allow for some interesting display settings as it allows you to set borders around just one cell or around just certain sides of cells (see the additional examples).

Now assume that we have multiple tables in our page to which we would like to apply this style. We can convert this Local style to a Global style by moving it into a STYLE tag within the <HEAD> tag of the page like this:

<STYLE>
TABLE{background-color:#74A9F8; font-family:arial; font-size:12pt; border:1px solid #000000}
</STYLE>

This style will now be applied to all tables in this page, unless there are conflicting Local settings. Since this is a Global setting, we need to specify the element to which we want to apply the style with a selector (TABLE). Then we can specify our property/value pairs inside the curly braces.

Of course, we can specify style settings for multiple elements in our Global setting. Assume that we want to add header cells (TH) to our table. These cells will be a different shade of blue and the text in them will be bold. Also, we wish to center the text in our table cells (TD). Here is what our new Global setting will look like:

<STYLE>
TABLE{background-color:#74A9F8; font-family:arial; font-size:12pt; border:1px solid #000000}
TH{background-color:#BFD9FF; font-weight:bold}
TD{text-align:center}
</STYLE>
We simply add the new selectors with their property/value pairs to the style setting. We can do this for as many elements as we want. Here is the result in Internet Explorer:

Intro to CSS - Example 3

Here is the HTML for the table. Notice that there is no stylistic formatting. That is all handled by the style settings.
<TABLE>
  <TR>
    <TH>Header #1</TH>
    <TH>Header #2</TH>
  </TR>
  <TR>
    <TD>Cell #1</TD>
    <TD>Cell #2</TD>
  </TR>
</TABLE>
Now, if we want to convert this Global setting to a Cascading setting so that multiple pages may use it, all we need to do is move the settings to an external style sheet (minus the STYLE tags). Here are the contents of our style sheet
TABLE{background-color:#74A9F8; font-family:arial; font-size:12pt; border:1px solid #000000}
TH{background-color:#BFD9FF; font-weight:bold}
TD{text-align:center}
You can create the style sheet using Notepad or any other text file editor. Then you call it from the pages using a LINK tag as discussed above. This style will now be applied to any table in any page that references this style sheet, provided there aren't any conflicting Global or Local settings.

Now suppose that we want the rest of the text on our pages to display in 12 point Arial font, just like our tables. We would want to set the font-family and font-size properties for the paragraph (<P>) and body (<BODY>) tags. Let's hard code the font color to black while we are at it. This will allow us to enforce consistency on our pages and give us the ability to change it easily later, if we want. We could simply add some more selectors to the style sheet like this:

TABLE{background-color:#74A9F8; font-family:arial; font-size:12pt; border:1px solid #000000}
TH{background-color:#BFD9FF; font-weight:bold}
TD{text-align:center}
P{font-family:arial; font-size:12pt; color:#000000}
BODY{font-family:arial; font-size:12pt; color:#000000}

But that seems redundant. Fortunately, we can specify property/value pairs for multiple selectors at once. Just separate the selectors with commas like this:

TABLE{background-color:#74A9F8; border:1px solid #000000}
TH{background-color:#BFD9FF; font-weight:bold}
TD{text-align:center}
P, BODY, TABLE{font-family:arial; font-size:12pt; color:#000000}

Here we have set the same font related property/value pairs for the Paragraph, BODY and TABLE tags with one entry. Notice that we still have a separate TABLE selector for the other settings. All of the settings are applied to our tables because there are no conflicting settings. What if there were conflicting settings? You shouldn't have conflicting settings in the same style sheet. That's just careless. But if you do, the setting that is specified last will be applied. So in the example above, the setting specified at the end of the sheet would take precedence over the first TABLE setting.

Of course, the fact that you can specify settings for multiple selectors this way doesn't mean you always have to. In fact, I prefer to isolate my selectors and specify the settings specifically for each one. I personally find it tedious to have to figure out how many selector settings in a sheet are being applied to a given element. I would probably code the sheet like this:

TABLE{background-color:#74A9F8; font-family:arial; font-size:12pt; border:1px solid #000000}
TH{background-color:#BFD9FF; font-weight:bold}
TD{text-align:center}
P, BODY{font-family:arial; font-size:12pt; color:#000000}

This way, there is only one selector for tables and therefore no chance of a conflict within the sheet. Since the settings for P and BODY are the same, I can combine them and still have a single selector for each of those elements.

We can also add comments to Global styles and Cascading Style Sheets. (You cannot put a comment inside a Local style. For that, just place a standard HTML comment near the tag.) CSS comments start with "/*" and end with "*/". Here is an example:

/* This is a CSS comment. */

Comments can be useful for explaining to yourself and others why the settings are set as such or what the purpose of a style class is (something we will discuss shortly). Note that CSS comments cannot be nested.

While we have not covered every aspect of CSS syntax in this section, we have hit all of the basics and this should be enough to get you started. Now, on to classes.

Style Classes

There may be cases where you want two or more different styles for the same element. This is where classes come in. Classes allow you to have different settings for different versions of the same element. These groups of settings are defined with a class name and may be used in Global or Cascading styles. The syntax for defining a class is as follows:

selector.class-name{property:value...}
The class name can be anything you want but should be descriptive.

Consider our ten pages with ten tables each example. Let's assume the following about these tables:

  • All of the tables will use 12 point Arial font and have a single pixel black border.
     
  • Many of the tables will have a blue background. These tables will display font in white.
     
  • Many of the tables will have a red background. These tables will display font in green.
     
  • Any other tables will have no background color and will use black as the font color.

Yes, these will be some rather ugly tables but using style classes will make them easier to change later. We will have general settings for all tables, one class for red tables called "RED", and one class for blue tables called "BLUE":

TABLE{font-family:arial; font-size:12pt; border:1px solid #000000; color:#000000}
TABLE.RED{background-color:#FF0000; color:#00FF00};
TABLE.BLUE{background-color:#0000FF; color:#FFFFFF};

We start by setting the font and border attributes with the normal TABLE selector because we want those attributes applied to all tables. We also specify the font color as black since that is the default for tables that are not red or blue. Next, we define a class called RED for the TABLE selector. Any table referencing this class will have a red background and green text. (The font color in the class overrides the generic font color we set for the TABLE selector.) Finally we define a BLUE class. Any table referencing this class will have a blue background and white text.

Now we just have to reference these classes in the appropriate TABLE tags. You reference a class by specifying the name of the class in the class attribute for that tag. Note that class names are not case sensitive. Below is a default table, a RED table and a BLUE table:

Intro to CSS - Example 4

And here is the HTML for these tables. The style settings above would be in an external style sheet or in a Global setting at the top of the page these tables are in.

<table>
  <tr>
    <td>Cell #1</td>
    <td>Cell #2</td>
  </tr>
</table>
<p>
<table class="RED">
  <tr>
    <td>Cell #1</td>
    <td>Cell #2</td>
  </tr>
</table>
<p>
<table class="BLUE">
  <tr>
    <td>Cell #1</td>
    <td>Cell #2</td>
  </tr>
</table>

Note that the first table uses the default settings and the other two call the appropriate class and use those settings.

It is also possible to create a generic class that any element may call. The syntax for this is the same as any other class except that you don't specify a selector. You still need a period before the class name, however, or the browser will mistake the class name for a selector. For example we could create the following generic class:

.RED_BOLD{font-weight:bold; color:#FF0000}

Any text element - a table, table cell, list, paragraph, body, etc - could use this class by having the attribute class="RED_BOLD" specified in the tag. Generic classes can be especially useful with the SPAN tag. For example, the following HTML:

Everything in default font except <span class="RED_BOLD">this part</span>.

produces this:

Intro to CSS - Example 4

This would be useful if you had a lot of things highlighted on your site in this manner. It ensures that the highlighting is consistent and if you decide to change the highlighting, you only need to change the style sheet and the change will cascade down to all of your pages.

There are also a number of pseudo-classes built into CSS. The most useful of these are used to control the display characteristics of hyperlinks (the <A> tag). These three classes, which can be treated like selectors, are A:LINK, A:ACTIVE, and A:VISITED. A:LINK controls the display of a link before the user clicks on it. A:ACTIVE control the display of a link that the user has clicked on and is being processed. A:VISITED controls the display of a link to a resource that the user has already visited.

To approximate the normal Internet Explorer display attributes, for example, you would set the following three pseudo-classes:

A:LINK{color:blue; text-decoration:underline}
A:ACTIVE{color:red; text-decoration:underline}
A:VISITED{color:purple; text-decoration:underline}

Of course, you can change any of these as you see fit. To get rid of the underlined links, for example, specify text-decoration:none. Changing these pseudo-classes does not require a class attribute in your <A> tags like a regular class would. 

You may also specify classes for these pseudo-classes. For example, if I wanted some of my un-clicked links to display in bold red text, I could set the following class for the A:LINK pseudo-class:

A.RED_BOLD:LINK{font-weight:bold; color:#FF0000}

Note that the class name is placed between the selector and the pseudo-class. In this case, I would have to change my <A> tag to reference the specific class:

<A class="RED_BOLD" href=...>

Be aware, however, that setting the styles for links overrides any settings that the user may have specified in their browser. Also note that setting these in a non-standard way can violate the government accessibility requirements for visually impaired users. Finally, most internet users are used to hyperlinks looking a certain way. That's how they know they are hyperlinks. So you should put a little thought into modifying these.

Additional Examples

In this section, we will take a look at a few real-world examples of CSS implementation.

We will use this page as our first example. You may may have noticed that all of the code samples in this article are in Courier New font and are indented. I could have accomplished this with HTML:

<BLOCKQUOTE>
<PRE><FONT face="Courier New" size="2">Code Sample</FONT></PRE>
</BLOCKQUOTE>
But that wouldn't be too efficient. Instead, I set a global style in this page for the PRE tag...
PRE{font-family:courier new; font-size:10pt; margin-left:35px}
...and my HTML looks like this:
<PRE>Code Sample</PRE>

Given the amount of code samples on this page, it's easy to see how much more efficient this is.

The next two examples are from a large software project I worked on. The software was an HTML based reference product consisting of hundreds of separate topics, each of which was an HTML document. For consistency and maintainability, this was clearly a project that would benefit from a cascading style sheet. 

To start, several attributes common to the body of all of the topics were set in the style sheet, including the background color, top and left margins, and the font characteristics:

BODY {
BACKGROUND-COLOR:FFFFEF;
MARGIN-TOP:15px;
MARGIN-LEFT:15px;
FONT-FAMILY:ARIAL;
FONT-SIZE:10pt
}
Note the way this style is written for easy readability, with each property/value pair on a separate line. This is perfectly acceptable as long as the pairs are separated by semicolons and the curly braces are in the right place.

The tables in this product had a distinctive look to them. Here is a sample:

Intro to CSS - Example 5

There are quite a few style settings to note about this table:

  • All of the text is 10 point Arial.
     
  • The column headers have a blue background and the text in them is bold, off-white, and centered.
     
  • The column headers and the table cells have a gray solid border, but the border does not appear on the left or right edges of the table. The cells on the ends appear "open" at the sides.
     
  • Although you cannot see it in this example, the cells are vertically aligned to the top.

Here are the pertinent entries in the style sheet:

TH.COL1 {
FONT-FAMILY:ARIAL; FONT-SIZE:10pt; FONT-WEIGHT:BOLD; COLOR:ADCFEF; TEXT-ALIGN:CENTER;
BACKGROUND-COLOR:0059AD;
BORDER-BOTTOM: 1PX SOLID #ADCFEF;
}
 
TH.COL2 {
FONT-FAMILY:ARIAL; FONT-SIZE:10pt; FONT-WEIGHT:BOLD; COLOR:ADCFEF; TEXT-ALIGN:CENTER;
BACKGROUND-COLOR:0059AD;
BORDER-BOTTOM: 1PX SOLID #ADCFEF;
BORDER-LEFT: 1PX SOLID #ADCFEF;
}

TD.COL1 {
FONT-FAMILY:ARIAL; FONT-SIZE:10pt;
VERTICAL-ALIGN:TOP;
BORDER-BOTTOM: 1PX SOLID #DEDFE7;
}
 
TD.COL2 {
FONT-FAMILY:ARIAL; FONT-SIZE:10pt;
VERTICAL-ALIGN:TOP;
BORDER-BOTTOM: 1PX SOLID #DEDFE7;
BORDER-LEFT: 1PX SOLID #DEDFE7;
}
Notice that we have separate settings for the column headers (<TH>) and table cells (<TD>) as they have different display characteristics. We also have two classes for each. This is because of the borders. The COL1 class is only for a header or cell in the first column and only has a border on the bottom edge. The COL2 class is for headers or cells in any other column and has a border on the bottom edge and the left edge. 

Here is the HTML for the table. Notice how the classes are called:

<TABLE cellspacing="0" cellpadding="3">
  <TR>
    <TH class="COL1">Header #1</TH>
    <TH class="COL2">Header #2</TH>
    <TH class="COL2">Header #3</TH>
  </TR>
  <TR>
    <TD class="COL1">Row #1 / Cell #1</TD>
    <TD class="COL2">Row #1 / Cell #2</TD>
    <TD class="COL2">Row #1 / Cell #3</TD>
  </TR>
  <TR>
    <TD class="COL1">Row #2 / Cell #1</TD>
    <TD class="COL2">Row #2 / Cell #2</TD>
    <TD class="COL2">Row #2 / Cell #3</TD>
  </TR>
</TABLE>

The product contained literally hundreds of tables like this, so having all of these specifications in a centralized location was critical.

This discussion has really only scratched the surface. Entire volumes have been written on CSS and its various implementations. Hopefully, this article has given you a good understanding of the basics and encouraged you to consider how you might be able to implement CSS in your web pages to improve their appearance and enhance their efficiency and maintainability.


References and Additional Information

The following are some references that I used to write this article and are excellent resources for additional information on CSS:

  • Webmaster in a Nutshell by Stephen Spainhour and Robert Eckstein. Published by O'Reilly Press, which also offers a number of excellent books specifically on CSS and other web technologies.
     
  • W3 Schools CSS Tutorial - a great CSS resource. This site offers its own tutorial and lots of great examples. This is also a good site to find out what CSS properties and values are available, and what browsers and versions of browsers they work in.
     
  • Taylor's Dynamic HTML Tutorial - DHTML makes interesting use of CSS by combining it with JavaScript to produce some wild results. This Web Monkey tutorial will provide you with a nice introduction.


© Copyright 2007, Gilsbach Designs