home | O'Reilly's CD bookshelfs | FreeBSD | Linux | Cisco | Cisco Exam  


Dynamic HTML: The Definitive Reference, 2rd Ed.Dynamic HTML: The Definitive ReferenceSearch this book

3.7. Common Subgroup Selectors

While a selector for a style sheet rule is often an HTML element name, that scenario isn' flexible enough for more complex documents. Consider the following possibilities:

Each of these possibilities calls for a different way of creating a new selector group or specifying an exception to the regular selectors. In an effort to distance design from content, CSS style sheets provide three simple ways of creating subgroups that can handle almost every design possibility:

Using these subgroup selectors requires special ways of defining selectors in style sheet rules. These selectors also require the addition of attributes to the HTML tags they apply to in the document. Because all CSS-enabled browsers support these CSS1 subgroup selectors, you should have these deeply ingrained in your authoring repertoire.

3.7.1. Class Selectors

A class selector is an identifier you can use to assign a style to a subset of elements in a document. To apply a class selector, you first invent an identifier for the class name. CSS2 guidelines for selector identifiers allow all Latin letters (a through z and A through Z), numerals (0 through 9), the hyphen, Unicode characters above 160, and escaped characters (characters that begin with a backslash character)—provided the name does not begin with a numeral or hyphen. Spaces are not permitted. For the sake of compatibility and the occasional browser bug, it is good practice to stick with Latin letters only. Version 6 browsers treat selectors in a case-sensitive manner, while earlier browsers do not. Therefore, the best forward- and backward-compatible practice is to observe case throughout, but not to reuse names with different combinations of upper- and lowercase letters.

The class identifier goes in both the style sheet rule and the HTML tag (assigned to the class attribute) for all elements that are to obey the rule. While the identifier name is the same in both cases, the syntax for specifying it is quite different in each place.

3.7.1.1. Binding a class identifier to an element type

In the style sheet rule, the class identifier is part of the rule's selector. When a class selector is intended to apply to only one kind of HTML element, the selector consists of the element name, a period, and the identifier. The following rule assigns a specific margin setting for all p elements flagged as belonging to the narrow class:

p.narrow {margin-left:5em; margin-right:5em}

To force a p element to obey the p.narrow rule, you must include a class attribute in the <p> tag and set the value to the class identifier:

<p class="narrow">Content for the narrow paragraph</p>

Any p elements that don't have the class attribute set to narrow follow the style applied to the generic p element. Example 3-1 shows a complete document that includes style sheet rules for all p elements and a subclass of p.narrow elements. The rule for all p elements specifies a 2-em margin on the left and right as well as a 14-pixel font size. For all p elements tagged with the class="narrow" attribute, the margins are set to 5 ems and the text color is set to red. Note the p.narrow rule inherits (or is affected by) style settings from the p rule. Therefore, all text in the p.narrow elements is displayed at a font size of 14 pixels. But when the margin attributes are set in both rules, the settings for the named class override the settings of the broader p element rule (the language of CSS doesn't include the object-oriented concepts of subclass or superclass). Following the inheritance trail one level higher in the containment hierarchy, all p elements (and all other elements in the document if there were any) obey the style sheet rule for the body element, which is where the font face is specified.

Example 3-1. Applying the p.narrow class rule

<html>
<head>
<title>Class Society</title>
<style type="text/css">
    p {font-size:14px; margin-left:2em; margin-right:2em}
    p.narrow {color:red; margin-left:5em; margin-right:5em}
    body {font-family:Arial, sans-serif}
</style>
</head>
  
<body>
<p>
This is a normal paragraph. This is a normal paragraph. This is a normal 
paragraph. This is a normal paragraph. This is a normal paragraph. 
</p>
<p class="narrow">
This is a paragraph to be set apart with wider margins and red color. This is a 
paragraph to be set apart with wider margins and red color. This is a paragraph 
to be set apart with wider margins and red color.
</p>
<p>
This is a normal paragraph. This is a normal paragraph. This is a normal 
paragraph. This is a normal paragraph. This is a normal paragraph. 
</p>
<p class="narrow">
This is a paragraph to be set apart with wider margins and red color. This is a 
paragraph to be set apart with wider margins and red color. This is a paragraph 
to be set apart with wider margins and red color.
</p>
</body>
</html>

3.7.1.2. Defining a free-range class rule

Most of the time, you don't want to limit a class selector to a single element type in a document. Fortunately, you can define a rule with a class selector that can be applied to any element in the document. The selector of such a rule is nothing more than the identifier preceded by a period. Example 3-2 contains a rule that assigns a red underline style to a class named hot. The hot class is then assigned to different elements scattered throughout the document. Notice inheritance at work in this example. When the hot class is assigned to a div element, it applies to the p element nested inside the div element: the entire paragraph is rendered in the hot style and follows the p.narrow rule as well, since the rules do not have any overlapping style attributes.

Example 3-2. Adding a free-range class selector

<html>
<head>
<title>Free Range Class</title>
<style type="text/css">
    p {font-size:14px; margin-left:2em; margin-right:2em}
    p.narrow {color:red; margin-left:5em; margin-right:5em}
    .hot {color:red; text-decoration:underline}
    body {font-family:Arial, sans-serif}
</style>
</head>
  
<body>
<h1 class="hot">Get a Load of This!</h1>
<p>
This is a normal paragraph. This is a normal paragraph. This is a normal 
paragraph. This is a normal paragraph. This is a normal paragraph. 
</p>
<div class="hot">
<p class="narrow">
This is a paragraph to be set apart with wider margins and red color. This is a 
paragraph to be set apart with wider margins and red color. This is a paragraph 
to be set apart with wider margins and red color.
</p>
</div>
<p>
This is a normal paragraph. This is a normal paragraph <span class="hot">but with a 
red-hot spot</span>. This is a normal paragraph. This is a normal paragraph. This 
is a normal paragraph. 
</p>
<p class="narrow">
This is a paragraph to be set apart with wider margins and red color. This is a 
paragraph to be set apart with wider margins and red color. This is a paragraph 
to be set apart with wider margins and red color.
</p>
</body>
</html>

3.7.2. ID Selectors

In contrast to the class selector, the ID selector lets you define a rule that applies to only one element in the entire document. Like the class selector, the ID selector requires a special way of defining the selector in the style sheet rule and a special attribute (id) in the tag that is the recipient of that rule. The same rules and warnings about defining class names also apply to ID names. Uniqueness within a document is critical not only for CSS ID selectors to work correctly, but especially for DHTML scripting. An element's id attribute value acts as a kind of address that scripts use to reference the element, regardless of document structure. This means that to maintain integrity of the object model for the current document, an id identifier must apply to only one element.

The style rule syntax for defining an ID selector calls for the identifier to be preceded with the # symbol. This can be in conjunction with an element selector or by itself. Therefore, both of the following rules are valid:

p#special4 {border:5px ridge red}
#special4{border:5px ridge red}

To apply this rule for this ID to a p element, you have to add the id attribute to that element's tag:

<p id="special4">Content for a special paragraph.</p>

There is an important difference between the two style rule examples just shown. By specifying the ID selector in concert with the p element selector in the first example, we've told the browser to obey the id="special4" attribute only if it appears in a p element. The second rule, however, is a generic rule. This means that the id="special4" attribute can appear in any kind of element. Since an id attribute value should be used in only one element throughout the entire document, the combined selector is redundant.

Example 3-3 shows the ID selector at work, where it is used to assign a rule (defining a red, ridge-style border for a block) to only one of several p elements in the document. Notice that it is assigned to a p element that also has a class selector assigned to it: two rules are applied to the same element. In this example, the style rules do not conflict with each other, but if they did, the cascade precedence rules (described later in this chapter) would automatically determine precisely which rule wins the battle of the dueling style attributes.

Example 3-3. Applying an ID selector to a document

<html>
<head>
<title>ID Selector</title>
<style type="text/css">
    p {font-size:14px; margin-left:2em; margin-right:2em}
    p.narrow {color:red; margin-left:5em; margin-right:5em}
    #special4 {border:5px ridge red}
    body {font-family:Arial, sans-serif}
</style>
</head>
  
<body>
<h1>Get a Load of This!</h1>
<p>
This is a normal paragraph. This is a normal paragraph. This is a normal 
paragraph. This is a normal paragraph. This is a normal paragraph. 
</p>
<p class="narrow" id="special4">This is a paragraph to be set apart with wider 
margins, red color AND a red border. This is a paragraph to be set apart with 
wider margins, red color AND a red border.
</p>
<p>
This is a normal paragraph. This is a normal paragraph. This is a normal 
paragraph. This is a normal paragraph. This is a normal paragraph. 
</p>
<p class="narrow">This is a paragraph to be set apart with wider margins and red 
color. This is a paragraph to be set apart with wider margins and red color. This 
is a paragraph to be set apart with wider margins and red color.
</p>
</body>
</html>

3.7.3. Descendant Selectors

One more way to assign styles to specific categories of elements is the descendant selector (formerly known as a contextual selector). To use a descendant selector, you should be comfortable with the containment hierarchy of elements in a document and how inheritance affects the application of styles to a chunk of content. Consider the two type selector rules in the following style sheet:

<style type="text/css">
    p {font-size:14px; color:black}
    em {font-size:16px; color:red}
</style>

This style sheet dictates that all em elements throughout the document be displayed in red with a 16-pixel font. If you were to add an em element as part of an h1 element, the effect might be less than desirable. What you really want from the style sheet is to apply the em style declaration to em elements only when they are contained by—are descended from—p elements. A descendant selector lets you do just that. In a descendant selector, you list the elements of the containment hierarchy that are to be affected by the style, with the elements separated by spaces.

To turn the second rule of the previous style sheet into a descendant selector, modify it as follows:

<style type="text/css">
    p {font-size:14px; color:black}
    p em {font-size:16px; color:red}
</style>

You still need the rule for the base p element in this case because the style is something other than the browser default. There is no practical limit to the number of containment levels you can use in a descendant selector. For example, if the design calls for a section of an em element to have a yellow background color, you can assign that job to a span element and set the descendant selector to affect a span element only when it is nested inside an em element that is nested inside a p element. Example 3-4 shows what the source code for such a document looks like. The example goes one step further, in that one element of the descendant selectors is a class selector (p.narrow). Each element selector in a descendant selector can be any valid selector, including a class or ID selector. You can also apply the same style declaration to more than one descendant selector by separating the descendant selector sequences with commas:

p em span, h3 em {background-color:yellow}

It's an odd-looking construction, but it's perfectly legal (and byte conservative).

Example 3-4. Applying a three-level descendant selector

<html>
<head>
<title>Descendant Selector</title>
<style type="text/css">
    p {font-size:14px; margin-left:2em; margin-right:2em}
    p.narrow {color:red; margin-left:5em; margin-right:5em}
    p.narrow em {font-weight:bold}
    p.narrow em span {background-color:yellow}
    #special4 {border:5px ridge red}
    body {font-family:Arial, sans-serif}
</style>
</head>
  
<body>
<h1>Get a Load of This!</h1>
<p>
This is a normal paragraph. This is a normal paragraph. This is a normal 
paragraph. This is a normal paragraph. This is a normal paragraph. 
</p>
<p class="narrow" id="special4">This is a <em>paragraph to be set apart</em> with 
wider margins, red color AND a red border. This is a paragraph to be set apart 
with wider margins, red color AND a red border.
</p>
<p>
This is a normal paragraph. This is a normal paragraph. This is a normal 
paragraph. This is a normal paragraph. This is a normal paragraph. 
</p>
<p class="narrow">This is a <em>paragraph to be <span>set apart</span></em> with 
wider margins and red color. This is a paragraph to be set apart with wider 
margins and red color. This is a paragraph to be set apart with wider margins and 
red color.
</p>
</body>
</html>

Note that a descendant selector points to any descendant of a parent element, even if the descendant is nested many levels deep in the containment hierarchy. To restrict a selector to an immediate child of an element, see Section 3.8.4 later in this chapter.



Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.