{margin-top: 0;} The selector is read as, "selects any paragraph that immediately follows an h1 element that shares a parent with the p element." To visualize how this selector works, it is easiest to once again consider a fragment of a document tree, shown in Figure 2-19 . Figure 2-19. Another document tree fragment In this fragment, a pair of lists descends from a div element, one ordered and the other not, each containing three list items. Each list is an adjacent sibling, and the list items themselves are also adjacent siblings. However, the list items from the first list are not siblings ofthe second, since the two sets of list items do not share the same parent element. (At best, they're cousins.) Remember that you can select the second of two adjacent siblings only with a single combinator. Thus, if you write li + li {font-weight : bold;} , only the second and third items in each list will be boldfaced. The first list items will be unaffected, as illustrated in Figure 2-20 . Figure 2-20. Selecting adjacent siblings To work properly, CSS requires that the two elements appear in "source order." In our example, an ol element is followed by a ul element. This allows you to select the second element with ol + ul , but you cannot select the first using the same syntax. For ul + ol to match, an ordered list must immediately follow an unordered list. In addition, text content between two elements does not prevent the adjacent-sibling combinator from working. Consider this markup fragment, whose tree view would be the same as that shown in Figure 2-19 :
List item 1
List item 1
List item 1
This is some text that is part of the 'div'.
A list item
Another list item
Yet another list item
Even though there is text between the two lists, you can still match the second list with the selector ol + ul . That's because the intervening text is not contained with a sibling element, but is instead part of the parent div . If you wrapped that text in a paragraph element, it would then prevent ol + ul from matching the second list. Instead, you might have to write something like ol + p + ul . As the following example illustrates, the adjacent-sibling combinator can be used in conjunction with other combinators: html > body table + ul{margin-top: 1.5em;} The selector translates as "selects any ul element that immediately follows a sibling table element that is descended from a body element that is itself a child of an html element." Warning Internet Explorer for Windows through IE6 does not support child and adjacent-sibling selectors. IE7 supports both.
Pseudo-Classes and Pseudo-Elements Things get really interesting with pseudo-class selectors and pseudo-element selectors . These selectors let you assign styles to structures that don't necessarily exist in the document, or to phantom classes that are inferred by the state of certain elements, or even by the state of the document itself. In other words, the styles are applied to pieces of a document based on something other than the structure of the document, and in a way that cannot be precisely deduced simply by studying the document's markup. It may sound like I'm applying styles at random, but I'm not. Instead, I'm applying styles based on somewhat ephemeral conditions that can't be predicted in advance. However, the circumstances under which the styles will appear are, in fact, well-defined. Think of it this way: during a sporting event, whenever the home team scores, the crowd will cheer. You don't know exactly when during a game the team will score, but when it does, the crowd will cheer, just as predicted. The fact that you can't predict the moment of the cause doesn't make the effect any less expected. Pseudo-Class Selectors Let's begin by examining pseudo-class selectors since they're better supported by