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.
If you're into math, the #sidebar p style has a specificity of 101 (100 for the ID, and 1 for the tag selector), while the .intro style has a specificity of 10 (10 points for a class selector). Since 101 is greater than 10, #sidebar p takes precedence. Changing .intro to #sidebar .intro changes its specificity to 110.
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).
Figure 5-4. Even though a class is applied to a specific tag—like the first paragraph in the top image—its properties may not always have an effect. In this case, the paragraph is inside a <div> tag with an ID of #sidebar, so the descendent selector #sidebar p is more specific than the .intro class. The solution: Make the .intro class more specific by adding the ID before it—#sidebar p.intro—as in the bottom example.
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).
Make sure you attach the external style sheet before the internal style sheet in the <head> section of the HTML. This ensures that the styles from the internal style sheet win out in cases where the specificity of two styles are the same, as explained on Specificity: Which Style Wins.
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"/>
Another way to fine-tune designs on a page-by-page basis is to use different ID names for the <body> tag of different types of pages—for example #review, #story, #home—and then create descendent selectors to change the way tags on these types of pages look. This technique is discussed on Creating and Applying an ID Selector.
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.
You don't have to type all this code yourself. You'll find a file named reset.css in the 05 tutorial folder at www.sawmac.com/css2e that contains a basic CSS reset file. Just copy the styles from this file and paste them into your own style sheets. A more comprehensive CSS reset (discussed on Eliminating Browser Style Interference) is available in the Chapter 15 tutorial files inside the 15 folder.
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.