Приглашаем посетить
Хомяков (homyakov.lit-info.ru)

Targeting Tags Within the Document Hierarchy

Previous Page
Table of Contents
Next Page

Targeting Tags Within the Document Hierarchy

If you have forgotten what the document hierarchy is since the end of the last chapter, you might want to reread "Document Hierarchy: Meet the XHTML Family" in Chapter 1 now so that I can avoid the redundancy of repeating myself repeatedly and redundantly.

Using Contextual Selectors

Targeting Tags Within the Document Hierarchy

To view the code discussed below, you can go to the Stylin' site (www.bbd.com/stylin) and download the template, contextual_selectors_tmpl.htm, and paste the styles between the style and /style tags in the head of the document, as indicated in the template. Then just open the document into your browser to see what those styles do to the markup.


If you write a rule where you simply use the tag name as the selector, then every tag of that type is targeted. For example, by writing

p {color:red;}

every paragraph would have red type.

But what if you only want one particular paragraph to be red? To target tags more selectively, you use contextual selectors. Here's an example

div p {color:red;}

Now only paragraphs within div tags would be red.

As you can see in example above, contextual selectors use more than one tag name (in this case, div and p) in the selector. The tag closest to the declaration (in this case the p tag) is the tag you are targeting. The other tag or tags state where the target tag must be located in the markup in order for it to be affected. Let's look at this idea in detail.

Targeting Tags Within the Document Hierarchy

If you are new to XHTML, note that span is a neutral container like div that has no default attributes: in other words, span has no effect on your markup until you explicitly style it. It's useful for marking up elements in your markup that have some meaning to you not defined by XHTML; however, if your document finds itself in an environment where it cannot use your style sheet, the spans will have no effect on the presentation. Unlike div, which is a block element and forces a new line, span is an inline element, and so it does not force a new line. By default, strong results in bold text, and em (emphasis) results in italics; but of course, you can use CSS to restyle them if you wish.


Take a look at this bit of markup


<h1>Contextual selectors are <em>very</em> selective.</h1>
<p>This example shows how to target a <em>specific</em> tag
  using the document hierarchy.</p>
<p>Tags only need to be descendants <span>in the <em>order stated</em> in the selector<
Targeting Tags Within the Document Hierarchy/span>; other tags can be in between and the selector still works.</p>

Both of paragraphs in the code above contain em tags, so if you were to write a rule to act on any em tags enclosed within p tags that rule would apply to both paragraphs. However, if you were to write a rule that applied only to the em tags inside of span tags inside of p tags, then the rule would only apply to the second paragraph.

Figure 2.3 shows how this code looks with just the browser's default styling.

Figure 2.3. Here, only the browser's default styles are applied.

Targeting Tags Within the Document Hierarchy


Figure 2.4 shows the markup's hierarchy.

Figure 2.4. This is the hierarchy for the code on the previous page.

Targeting Tags Within the Document Hierarchy


This hierarchy diagrammatically shows which tag is inside which. If you write this style

em {color:green}

for the markup on the previous page by adding it between the style tags in the head of the template found at www.bbd.com/stylin then, as you learned in the "Writing CSS Rules" earlier in the chapter, all the text in em tags would turn green (Figure 2.5).

Figure 2.5. In this example, all text within em tags is green.

Targeting Tags Within the Document Hierarchy


But what if you want to be more selective? Let's say you only want the em text within the paragraphs to be green. If this is the case, you would write a rule like this

p em {color:green}

which would result in Figure 2.6.

Figure 2.6. By adding a contextual selector, you cause the rule to affect only paragraphs, not the heading.

Targeting Tags Within the Document Hierarchy


Because you preceded the em with a p in the selector, only em tags within p tags are now targeted by the rule; the em tag in the h2 tag is no longer affected. Note that, unlike the group selectors you saw earlier, contextual selectors have spaces, not commas, between the selectors.

Rules with group selectors cause the rule to be applied to all the tags listed, whereas rules with contextual selectors are applied only to the last tag listed, and then only if the selectors that precede it appear in this same order somewhere in the hierarchy above it. It doesn't matter how many tags appear in between.

Because of this, the em tag within the span tag is affected by this rule. Even though it is not a child of the p tag; the rule still applies, because it is a descendant of the p tag. (You may want to read "Document Hierarchy: Meet the XHTML Family" in Chapter 1 again if this does not make sense to you.)

Here's an example of how you can state multiple tags in the selector to make the targeting even more specific

p span em {color:green}

This results in Figure 2.7.

Figure 2.7. With three elements in the selector, you can get very specific about which text will be green.

Targeting Tags Within the Document Hierarchy


Your rule now states that only an em within a span within a p tag is selected; you set a very specific context in which the rule works, and only one tag meets this criterion. In a contextual selector like this, you can list as many selectors as you need to ensure that the tag you want to modify is targeted.

However, things get more difficult if you want to target the word "specific" only; as you saw in Figure 2.5, the rule p em {color:green:} selects the em tags inside both the paragraphs and you simply can't target just this particular tag with a standard contextual selector. What you need here is a child selector.

Working with Child Selectors

In Chapter 1 I mentioned that a child tag is a direct descendant of an enclosing tag. If you want to write a rule so that the tag you're targeting has to be a child of a particular tag, then you can do that too, like this

p>em {color:green;}

Targeting Tags Within the Document Hierarchy

The > symbol is used between the two selectors to mean "child of."


Now you have successfully targeted the word "specific" without affecting the other em text, because "specific" is contained in an em tag that is a child of the p tag, but the words "ordered stated" are not (Figure 2.8).

Figure 2.8. A child selector provides the required context to select the word "specific" in this markup.

Targeting Tags Within the Document Hierarchy


Before you drop this book in your haste to start using child selectors in your CSS, it's important to know that, at the time of writing, IDWIMIE, Internet Explorer for Windows simply ignores them (although Internet Explorer for Macintosh does implement them). However, there are work-arounds if you find yourself in situations where only a child selector will do. As you will see shortly, classes and IDs let you target any individual tag you wish, but to use them, you'll need a little extra markup.

So until there's a version of Internet Explorer that can understand child selectors, you'll mainly use child selectors to create variations in your style sheet to work around Internet Explorer's various non-standards-compliant quirks. We will use them in this way in later chapters.

Adding Classes and IDs

So far you've seen that when you have a rule with a selector that simply states a tag name such as p or h1, the rule is applied to every instance of that tag. You've also seen that to be more specific in the selection process, you can use contextual selectors to specify tags within which target tags must be contained.

However, you can also target specific areas of your document by adding IDs and classes to the tags in your XHTML markup. IDs and classes give you a second approach to styling your documentone that can operate without regard for the document hierarchy.

SIMPLE USE OF A CLASS

Let me use this piece of markup to illustrate how you might use a class


<h1 class="specialtext">This is a heading with the <span>same class</span> as the second
Targeting Tags Within the Document Hierarchy paragraph</h1>
<p>This tag has no class.</p>
<p class="specialtext"> When a tag has a class attribute, we can target it
Targeting Tags Within the Document Hierarchy <span>regardless</span> of its position in the hierarchy.</p>

Note that I've added the class attribute specialtext to two of these tags. Let's now apply these styles to this markup where specialtext is formatted as bold (Figure 2.9)

Figure 2.9. Here I use a class selector to bold two different tags.

Targeting Tags Within the Document Hierarchy


Targeting Tags Within the Document Hierarchy

When you write a class selector, start it with a . (period).


p {font-family: Helvetica, sans-serif;}
.specialtext {font-weight:bold;}

These rules result in both paragraphs displaying in the Helvetica font (or the browser's generic sans-serif font if Helvetica is not available) and the paragraph with the specialtext class displaying in Helvetica bold. The text in the h1 tag remains in the browser's default font (usually Times) but it is bold, because it also has the specialtext class. Note that the span, a tag that has no default attributes, does nothing because I didn't explicitly style it.

CONTEXTUAL CLASS SELECTORS

If you only want to target one paragraph with the class, you create a selector that combines the tag name and the class, like this (Figure 2.10)

p {font-family: Helvetica, sans-serif;}
.specialtext {font-weight:bold;}
p.specialtext {color:red}

Figure 2.10. By combining a tag name and class name, you make the selector more specific.

Targeting Tags Within the Document Hierarchy


This is another kind of contextual selector because the class must be in the context of a paragraph for the rule to be applied.

You can go one step further and write the following (Figure 2.11)

p {font-family: Helvetica, sans-serif;}
.specialtext {font-weight:bold;}
p.specialtext {color:red}
p.specialtext span {font-style:italic}

Figure 2.11. By adding a second selector, you can be very specific about which tag is styled.

Targeting Tags Within the Document Hierarchy


Now the word "regardless" is bold and italicized because it is in a span tag that is in a paragraph with the specialtext class, as the rule specifies. If you also want this rule to target the span in the H1 tag, you can modify it in one of two ways. The easiest way is to not associate the class with any specific tag (Figure 2.12).

.specialtext span {font-style:italic}

Figure 2.12. With a less specific selector, the headline's span text is also selected.

Targeting Tags Within the Document Hierarchy


The word "class" in the headline is now also italicized. By deleting the p from the start of the selector, you remove the requirement for the class to be attached to any specific tag, so now both span tags are targeted. The rule states the span tag can be a descendant of any tag with the specialtext class because no tag is specified.

The benefit of this approach is that you can use a class without regard for the tag to which it belongs, so you are escaping the inherent constraints of the hierarchy when you do this.

The downside is that other tags that you don't intend to style might also be affected because this modified rule is less specific than it was. So, say you later added a span inside another tag that also had the specialtext class, such as this one


<div class="specialtext">In this div, the span tag <span>may or may not</span> be styled.<
Targeting Tags Within the Document Hierarchy/div>

The text within the span would be italicized also, which may or may not be the desired effect (Figure 2.13).

Figure 2.13. The less specific the selector, the more likely other tags will be inadvertently targeted.

Targeting Tags Within the Document Hierarchy


If you don't want to style this new div's span, you can adopt a second, more focused, group selector approach, like this (Figure 2.14)

p.specialtext span, h1.specialtext span {font-style:italic}

Figure 2.14. By using two grouped rules, you focus your targeting to specific tags.

Targeting Tags Within the Document Hierarchy


Now only the two tags in question are targeted and your new tag is not affected. Your grouped rules don't target that span because it's descended from a div, whereas if you use the more simple and less specific .specialtext span approach, it is selected.

Although this may seem like a lot to think about when you are styling a four-line example like this, when you are working on a style sheet that might be dozens or hundreds of lines long, you need to keep these considerations in mind, as we do in later chapters.

Introducing IDs

IDs are written in a similar way to classes, except you use a # (hash symbol) to indicate them instead of the class's . (period)

#specialtext {font-weight:bold;}

If a paragraph is marked up with an ID, like this

<p id="uniquetext">This is the special text</p>

then the corresponding contextual selector looks like this

p#uniquetext {some CCS rules here}

Other than this, IDs work in the same way as classes, and everything in our discussion of classes above applies equally to IDs. So what's the difference?

The Difference Between IDs and Classes

So far, I have shown aspects of classes and IDs that might make them seem to be interchangeablewe have used them both to identify a specific tag within our markup. However, an ID is more powerful than a class, rather like the queen is more powerful than a pawn in a game of chess. (You will see just how true this is when you look at the concept of rule specificity in the "The Cascade" section later in this chapter.) To extend this queen/pawn chess analogy, according to the rules of XHTML, only a single instance of a particular ID (such as id="mainmenu") can be in a page, but a class (such as class="strongparagraph") can appear many times.

So, if you want to identify a unique piece of your page's markup, such as the main navigation menu to which you want to target a special set of CSS rules, use an ID. To identify a number of paragraphs in a page that all require the same styling, use a class.

You also use an ID to enable JavaScript to be targeted at a tag (for example, to activate a DHTML animation when the user mouses over a link). You JavaScript jocks might like to know that the id attribute replaces the deprecated name attribute (which the XHTML validator flags as invalid) that was formerly used for this purpose. It's especially important that you make sure JavaScript-related IDs appear only once in a page, or the JavaScript may behave unpredictably.

Don't Go Crazy with Classes

Generally, you should use IDs and classes sparingly; the right kind of use is putting them on the divs that contain the main sections of your markup, and then accessing the tags within them with contextual selectors that begin with the ID or class's name.

What you want to avoid is what Jeffrey Zeldman describes as "classitisthe measles of markup," where you add a unique class or ID to just about every tag in your markup and then write a rule for each one. This is only one step removed from loading up your markup with FONT tags and other extraneous markup. The good doctor Zeldman has cured me and many others of this nasty affliction. If you are already in the habit of slapping classes on every tag, as most of us do when we enthusiastically jump into CSS, take a look at the markup sample in Chapter 1 in light of what you just read in this chapter. You'll see that you can target styles at every tag quite easily without adding any more IDs or classes.

If you use IDs and classes to identify only the main sections of your markupand those occasional tags that can't be specifically targeted with contextual tag-based selectorsyou won't go far wrong. This has the added benefit of making your style sheet simpler too.


To be clear, you can use multiple id attributes in a page, but each one must have a unique value (name) to identify it. You can apply a particular class to as many tags as you need to. Let's now take quick look at some other selectors that you may not use as much as contextual selectors, classes, and IDs, but which offer powerful capabilities just the same.

The Universal Selector

The * (asterisk) selector means "anything," so if you use

* {color:green;}

in your style sheet, all type will be green except where you specify it to be different in other rules. Another interesting use for this selector is as the inverse of the child selectora not-a-child selector, if you will.

p * em {font-weight:bold;}

Here, any em tag that is at least a grandchild of the p tag, but not a child, is selected; it doesn't matter what the em's parent tag is.

The Adjacent Sibling Selector

This rule selects a tag that follows a specific sibling tag (sibling tags are at the same level in the markup hierarchythat is, they share the same parent tag). Here's an example

h1 + p {font-variant:small-caps}

Applying this rule to this markup


<div>
   <h1>All about siblings selectors</h1>
   <p>There must be at least two selectors, with a + sign before the last one.</p>
   <p>The targeted selector will only be affected if it is a sibling to, and preceded by,
Targeting Tags Within the Document Hierarchy the one before the + sign.</p>
</div>

results in what is shown in Figure 2.15, because only the first paragraph is preceded by a sibling H1 tag.

Figure 2.15. Sibling selectors work based on the preceding tag in the markup, and both must be nested at the same level. This is one of the trickier selectors to understand.

Targeting Tags Within the Document Hierarchy


As you can see, the p tag that follows the h1 meets the condition of the rule and so it is in small caps. The second p tag, which is not adjacent to the h1, is unaffected. (This doesn't hold true for Internet Explorer for Windows).

Attribute Selectors

Attribute selectors use the attributes of the tag. They are primarily used in XML but have their uses in XHTML too.

This rule

img [title] {border: 2px solid blue;}

causes any img with a title tag, like this

<img src="/images/011/sunset.jpg" alt="Lahina Sunset" title="Lahina Sunset">

to have a blue, 2-pixel border around it; it doesn't matter what the value of the title attribute is, just that there is one. You might use such a style to indicate to the user that if they point at this image, a tool tip (pop-up text generated by the title attribute) displays. (It's common practice to duplicate the alt and title attribute valuesthe <alt> tag text displays if the image does not load, or can be read by an audio reader, and the title causes a tool-tip to appear if the user points at the image.

You can also be specific about what the attribute's value should be. For example, the rule

img [alt="Stylin logo"] {border: 2px solid blue;}

only puts the border around the image if the image's alt attribute is "Stylin logo"; in other words, if the image markup looks something like this

<img src=/images/011/stylin_logo" alt="Stylin logo">

This rule is made more useful by the fact that it lets you specify just the first characters of the attribute value, but the "common" part of the attribute must be separated from the "different" part of the attribute with a hyphen. So, if you have carefully written your img tags with attributes like these

<img src="/images/011/car1.gif" alt="car-toyota_prius">
<img src="/images/011/car2.gif" alt="car-honda_accord">

then you can select them by adding the pipe symbol (usually typed with Shift-/) into your rule, like this

Targeting Tags Within the Document Hierarchy

The text of these image alt tag examples are deliberately very brief for the sake of clarity. From an accessibility point of view, however, always write alt text that is meaningful for a user who can't see the image.


img [alt|="car"] {border: 2px solid blue;}

By the way, this rule would also select this example

<img src="/images/011/car_montage.gif" alt="car">

even though this example's alt tag doesn't have the hyphenated extension to the value.

Summary of Selectors

So far, you've seen that you can target CSS rules in several ways: by using tag selectors, by using class and ID selectors, by using selectors that are a combination of both, and even by selecting based on the attributes that are attached to the tag.

One common aspect of these selectors is that they all are targeting something in the markupa tag name, a class, an ID, an attribute, or an attribute value. But what happens if you want some kind of styling to happen when some event occurs, such as the user pointing at a link? In short, you want a way to apply rules based on events. And of course, after all this build-up, you know I'm going to tell you there's a way to do that.

    Previous Page
    Table of Contents
    Next Page