CSS 3 introduces a wide range of new selectors that let you specify which page elements a style applies to with even greater precision. In fact, several of the attribute selectors discussed on pages Attribute Selectors–Tutorial: Selector Sampler are actually CSS 3 selectors. For example, to style links that point to Adobe Acrobat files, you can create a selector like this: a[href$=".pdf"]. The $= means "ends with," so the specified attribute (here, href) has to end with a particular value (.pdf). Similarly, you can use ^= to pinpoint an attribute that starts with a particular value (Attribute Selectors explains how to use this selector to identify links to another website).
The advanced attribute selectors in this section work with Firefox, Safari, Chrome, Opera, and even Internet Explorer 7 and above (but not IE 6, mind you). Other new CSS 3 selectors work mostly in non-IE browsers.
If you want to see which CSS 3 selectors your favorite web browser understands, visit the CSS Selectors Test Suite at www.css3.info/selectors-test. This nifty JavaScript program tests your browser, giving either a green (thumbs up) or red (thumbs down) rating for each of the CSS 3 selectors. Safari 4, Firefox 3.5, Opera 9.5, and Chrome pass all 43 tests, while Internet Explorer 8 passes 22 of the 43 tests.
CSS provides several methods for formatting tags that are children of other tags. As described on The HTML Family Tree, a child is any tag that's directly wrapped inside a tag. Take, for example, a bold word inside a paragraph; the <strong> tag is the child of the <p> tag. In a bulleted list of items, the <li> tags are children of the <ul> tag.
:first-child. You've seen this selector before, on :first-child. Actually part of the CSS 2 standard, it lets you format just the first child of a tag—see top-left image in Figure 16-2. For example, to format the first list item in a bulleted list, you can write this selector:
ul :first-child
Note the space between ul and :first-child, which translates to "find the first child of a <ul> tag." (The selector ul:first-child, with no space, is entirely different: it selects all <ul> tags that are a first child of some other tag.)
If you want to add a special color to any text that appeared first inside a div with the class announcement, write the following style:
.announcement :first-child { color: #F33F00; }
This style applies to the first tag inside the div, whether it's an <h1>, <h2>, <p>, or any other tag. It gives you extra flexibility, since the style isn't dependent on an exact type of tag to appear first inside the div.
The :first-child, selector works in all modern browsers except Internet Explorer 6 and earlier.
Figure 16-2. CSS's wide range of child selectors gives you a variety of ways to select child elements. These selectors are great when you want to highlight the first, last, or an alternating number of items in a list.
:last-child. This selector is new in CSS 3 and applies to the last child within a tag. You can use it, for example, to add a borderline to the bottom of the last paragraph of a div or to highlight the last item in a list (see second from left image in the top row of Figure 16-2). This selector doesn't work in any version of Internet Explorer (even IE 8).
:nth-child( ). This complex selector is very useful. With it, you can easily style every other row in a table, every third list item, or style any combination of alternating child elements (see Figure 16-2).
:nth-child( ). This selector requires a value to determine which children to select. The easiest option is a keyword—either odd or even—which lets you select alternating odd or even child elements. For example, if you want to provide one background color for each even row in a table and another color in the background of each odd-numbered row, you can write two styles like this:
table tr:nth-child(odd) { background-color: #D9F0FF; } table tr:nth-child(even) { background-color: #FFFFFF; }
Now that's a really simple way to color alternating table rows (see Figure 16-3). But :nth-child( ) has even more power up its sleeve. You can also select, say, every third child element in a series, starting with the second child element. For example, suppose you want to highlight every third table cell (<td> tag) inside a row, starting with the second table cell (see Figure 16-3). Here's a style to achieve that:
tr td:nth-child(3n+2) { background-color:#900; }
Basically, the number before the n (3 in this case) represents which child element you're after. So, 3n means every third element, while 4n means every fourth element. The plus sign followed by a number (+2 in this example) indicates which element to start at, so +2 means start at the second child element, while +5 means start at the fifth child element. So :nth-child(5n + 4) selects every fifth child element starting at the fourth child element.
Unfortunately, version 8 and earlier of Internet Explorer do not support the nth-child selector. (For IE 6, 7 and 8 you can use the lower-tech solution for striping tables, described on Styling Rows and Columns, which works in all browsers.)
Figure 16-3. Table-striping the easy way: with child selectors. You can even stripe alternating columns by targeting every other <td> tag within a row, or, as in this case, every third column beginning with the second one. Now that's precision! Unfortunately, this technique doesn't work in the most common browser in the world—Internet Explorer.
CSS 3 introduces a selector that works much like the child selectors in the previous section but applies to children with a specific type of HTML tag. For example, say you want to format the first paragraph inside a sidebar in a particular way, but on some pages, that sidebar starts with an <h2> tag, and on other pages, it starts with a <p> tag. You can't use :first-child to select that paragraph, since in some cases it's the second child (following the <h2>). However, it's always the first paragraph (<p> tag), even if other tags come before it, so you can select it with a type selector called :first-of-type.
Here's the skinny on :first-of-type and several more type-related selectors:
:first-of-type. Works just like :first-child but applies to a child that has a particular tag. For example, say you have a sidebar element with the ID sidebar. To style the first paragraph in that sidebar, use this selector:
#sidebar p:first-of-type
Notice the p in p:first-of-type. It indicates the tag you're going to format.
:last-of-type. Works like :last-child but applies to the last instance of a particular type of tag. For example, if you want to format the last paragraph in the sidebar div in a particular way, but you're not sure whether there are other tags coming after the paragraph (like a bulleted list, headline, or image). Here's the style:
#sidebar p:last-of-type
:nth-of-type( ). Works like :nth-child( ) but it applies to alternating children that have a specific tag. You may find this selector handy if you have something like a big paragraph of text that's peppered with photos. The <img> tag is an inline tag, so you can have a <p> tag with a bunch of <image> tags inside it. And say you want to alternately float the images left and right, as shown in Figure 16-4. You can do so with these two styles:
img:nth-of-type(odd) { float: left; } img:nth-of-type(even) { float: right; }
As you can see, you use the same keywords (odd or even) and formula (here, 2n +1) for :nth-of-type( ) as you do for :nth-child( ).
Figure 16-4. The :nth-of-type( ) selector you can easily select every other image inside a tag, alternating between left and right alignment.
Unfortunately, the type selectors don't work in Internet Explorer 8 or earlier; just Firefox 3.5, Safari, Opera, and Chrome.
For a complete list of CSS 3 selectors, visit www.w3.org/TR/css3-selectors.