Controlling the Cascade

As you can see, the more CSS styles you create, the greater the potential for formatting snafus. For example, you may create a class style specifying a particular font and font size, but when you apply the style to a paragraph, nothing happens! This kind of problem is usually related to the cascade. Even though you may think that directly applying a class to a tag should apply the class's formatting properties, it may not if there's a style with greater specificity.

You have a couple of options for dealing with this kind of problem. First, you can use !important (as described in the box above) to make sure a property always applies. The !important approach is a bit heavy handed, though, since it's hard to predict that you'll never, ever, want to overrule an !important property someday. Read on for two other cascade-tweaking solutions.

The top picture in Figure 5-4 is an example of a specific tag style losing out in the cascade game. Fortunately, most of the time, you can easily change the specificity of one of the conflicting styles and save !important for real emergencies. In Figure 5-4 (top), two styles format the first paragraph. The class style—.intro—isn't as specific as the #sidebar p style, so .intro 's properties don't get applied to the paragraph. To increase the specificity of the class, add the ID name to the style: #sidebar .intro.

You can also fine-tune your design by selectively overriding styles on certain pages. Say you've created an external style sheet named global.css that you've attached to each page in your site. This file contains the general look and feel for your site—the font and color of <h1> tags, how form elements should look, and so on. But maybe on your home page, you want the <h1> tag to look slightly different than the rest of the site—bolder and bigger, perhaps. Or the paragraph text should be smaller on the home page, so you can wedge in more information. In other words, you still want to use most of the styles from the global.css file, but you simply want to override a few properties for some of the tags (<h1>, <p>, and so on).

One approach is to simply create an internal style sheet listing the styles that you want to override. Maybe the global.css file has the following rule:

h1 {
  font-family: Arial, Helvetica, sans-serif;
  font-size: 24px;
  color: #000;
}

You want the <h1> tag on the home page to be bigger and red. So just add the following style in an internal style sheet on the home page:

h1 {
  font-size: 36px;
  color: red;
}

In this case, the <h1> tag on the home page would use the font Arial (from the external style sheet) but would be red and 36 pixels tall (from the internal style).

Another approach would be to create one more external style sheet—home.css for example—that you attach to the home page in addition to the global.css style sheet. The home.css file would contain the style names and properties that you want to overrule from the global.css file. For this to work, you need to make sure the home.css file appears after the global.css file in the HTML, like so:

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

As discussed on The Limits of Inheritance, browsers apply their own styles to tags: for example, <h1> tags are bigger than <h2> tags, and both are bold, while paragraph text is smaller and isn't bold; links are blue and underlined; and bulleted lists are indented. There's nothing in the HTML standard that defines any of this formatting: Web browsers just add this formatting to make basic HTML more readable. However, even though browsers treat all tags roughly the same, they don't treat them identically.

For example, Safari and Firefox use the padding property to indent bulleted lists, but Internet Explorer uses the margin property. Likewise, you'll find subtle differences in the size of tags across browsers and an altogether confusing use of margins among the most common web browsers. Because of these inconsistencies, you can run into problems where, for instance, Firefox adds a top margin, while Internet Explorer doesn't. These types of problems aren't your fault—they stem from differences in the built-in browser styles.

To avoid cross-browser inconsistencies, it's a good idea to start a style sheet with a clean slate. In other words, erase the built-in browser formatting and supply your own. The concept of erasing browser styling is called CSS reset. This section gives you a working introduction.

In particular, there's a core set of styles you should include at the top of your style sheets. These styles set a baseline for properties that commonly are treated differently across browsers.

Here's a bare-bones CSS reset:

html, body, h1, h2, h3, h4, h5, h6, p, ol, ul, li, pre, code, address,
variable, form, fieldset, blockquote {
  padding: 0;
  margin: 0;
  font-size: 100%;
  font-weight: normal;
}
ol {
  margin-left: 1.4em;
  list-style: decimal;
}
ul {
  margin-left: 1.4em;
  list-style:square;
}
img {
  border: 0;
}

The first style is a very long group selector (Constructing Group Selectors) that takes the most common tags and "zeros" them out—removing all the padding and margins, setting their base text size to 100% and removing bold text formatting. This step makes your tags look pretty much identical (see Figure 5-5), but that's the point—you want to start at zero and then add your own formatting so that all browsers apply a consistent look to your HTML.

The second and third styles (the ol and ul tag styles), set a consistent left margin and style (Formatting Lists introduces list styling), and the last style removes a border that some browsers add to images that are links.