6 Selectors

Contents

  1. Type selectors
  2. Grouping
  3. Attribute selectors
    1. Matching attributes, single values, and multiple values
    2. The class and id attribute in HTML
    3. The class attribute in other document languages: @class
    4. The id attribute
  4. Contextual selectors
  5. Parent-child selectors
  6. Sequential selectors
  7. Pseudo-elements and pseudo-classes
    1. The :first-line pseudo-element
    2. The :first-letter pseudo-element
    3. Overlapping pseudo-elements
    4. Pseudo-elements with contextual selectors
    5. Anchor pseudo-classes: :link, :active, and :visited
    6. Combining pseudo-elements with normal classes
    7. Colliding attribute selectors and pseudo-classes

In CSS, pattern matching rules determine which style rules apply to elements in a document. These patterns, called selectors,  may range from simple element types to rich contextual patterns. If all conditions in the pattern are true for a certain element, the selector matches the element.

6.1 Type selectors

The simplest selector is the name of an element from the document language, called a type selector.  Type selectors match all instances of the element type in the document. Element type names are case-insensitive if the document is in HTML, and case-sensitive if it is in XML.

For example, the following rule matches all H1 elements in a document:

  H1 { font-family: Helvetica }

6.2 Grouping

When element selectors share the same declarations, they may be grouped into comma-separated lists.

In this example, we condense three rules with identical declarations into one. Thus,

  H1 { font-family: Helvetica }
  H2 { font-family: Helvetica }
  H3 { font-family: Helvetica }

is equivalent to:

  H1, H2, H3 { font-family: Helvetica }

Furthermore, multiple declarations for the same selector may be organized into semi-colon separated groups.

Thus, the following rules:

  H1 { font-weight: bold }
  H1 { font-size: 12pt }
  H1 { line-height: 14pt }
  H1 { font-family: Helvetica }
  H1 { font-variant: normal }
  H1 { font-style: normal }

are equivalent to:

  H1 { 
    font-weight: bold; 
    font-size: 12pt;
    line-height: 14pt; 
    font-family: Helvetica; 
    font-variant: normal;
    font-style: normal;
  }

In addition, some properties are shorthand  rules that allow authors to specify the values of several properties with a single property. For instance, the 'font' property is a shorthand property for setting 'font-style', 'font-variant', 'font-weight', 'font-size', 'line-height', and 'font-family' all at once.

The multiple style rules of the previous example:

  H1 { 
    font-weight: bold; 
    font-size: 12pt;
    line-height: 14pt; 
    font-family: Helvetica; 
    font-variant: normal;
    font-style: normal;
  }

may be rewritten with a single shorthand property:

  H1 { font: bold 12pt/14pt Helvetica }

Note that since 'font-variant' and 'font-style' take their default values of 'normal' in this example, these values have been omitted from the shorthand form.

6.3 Attribute selectors

CSS2 allows authors to specify rules that match according to attributes defined in the document language. A rule may match based on the simple presence of the attribute, or on one or more values for the attribute.

6.3.1 Matching attributes, single values, and multiple values

An attribute selector can select on the simple presence or absence of an attribute, on the attribute and its value, or on the attribute and one word in its value. The syntax is [att], [att=val], and [att~=val] respectively.

For example, the following rule matches all H1 elements that specify the "href" attribute, whatever its value:

   H1[href] { color: blue; }

In the following example, the rule matches all SPAN elements whose "class" attribute has the value "example":

   SPAN[class=example] { color: blue; }

The case-sensitivity of attribute values depends on the document language. For example, in HTML, attribute values are case-insensitive, but in XML they are case-sensitive.

Attribute values must be quoted or escaped if they are not identifiers.

Document languages may allow multi-valued attributes, typically space-separated lists such as the following:

<SPAN class="fish fresh-water edible">perch</SPAN>

To accommodate value lists such as this, CSS2 defines the following two types of equality:

The "=" sign

For the rule to apply, the value following "=" must match the whole attribute value.

The "~=" sign

For the rule to apply, the string following "~=" must match at least one member of the space-separated list of attribute values. With the "~=" operator, attribute values cannot contain spaces.

The following rules illustrate the differences between "=" and "~=":

   A[rel~="copyright"] {...} /* matches, e.g., <A rel="copyright copyleft ..." */
   td[colspan="2"] {...}   /* matches only <TD colspan="2"> ... */

The following rule hides all elements for which the value of the "lang" attribute is "fr" (i.e., the language is French).

[LANG=fr] { display : none }

6.3.2 The class and id attribute in HTML

Although authors may refer to any attributes with the generic syntax "[attribute=value]" and "[attribute~=value]", CSS2 defines a special syntax for two [HTML40] attributes: "class" and "id".

The HTML "class" attribute allows authors to group elements together and specify style information for the entire group. The CSS2 shortcut syntax for "[class~=value]" is a "." followed by the class value, with no intervening white space.

For example, we can assign style information to all elements with class="pastoral":

  .pastoral { color: green }  /* all elements with class=pastoral */

or just to H1 elements with class="pastoral":

  H1.pastoral { color: green }  /* H1 elements with class=pastoral */

Given these rules, the first H1 instance below would not have green text, while the second would:

  <H1>Not green</H1>
  <H1 class="pastoral">Very green</H1>

Note that "H1.pastoral" is equivalent to "H1[class~=pastoral]".

To match a subset of "class" values, each value must be preceded by a ".", in any order.

For example, the following rule matches any P element whose "class" attribute has been assigned a list of space-separated values that includes "pastoral" and "marine":

 
   P.pastoral.marine { color: green }

This rule matches when class="pastoral blue aqua marine" but does not match for class="pastoral blue".

Similarly, the following aural style sheet rules allow a script to be read aloud in different voices for each role:

   P.role.romeo  { voice-family: romeo, male }
   P.role.juliet { voice-family: juliet, female }

Note. CSS gives so much power to the "class" attribute, that in many cases it doesn't matter what HTML element the class is set on -- you can make any element emulate almost any other. Relying on this power is not recommended, since it removes the level of structure that has a universal meaning (HTML elements). A structure based on "class" is only useful within a restricted domain, where the meaning of a class has been mutually agreed upon.

6.3.3 The class attribute in other document languages: @class

CSS2 allows authors to use the class selector syntax (a "." followed by a class value) for arbitrary attributes, instead of for "class". If the attribute that authors want to use with the dot-syntax is not called "class", authors must specify which attribute will be acting as the "class" attribute. This is done with the @class  rule, which has the form "@class <attribute-name>;".

For instance, to specify that the "type" attribute of XML has the role of assigning class information, authors should include the following declaration in their style sheets:

   @class type;

Then, a rule for XML such as:

   PARA.romeo { ... }

would be equivalent to:

   PARA[type~=romeo] { ... }

@class declarations must obey the following rules:

A style resource is either

  1. a style sheet corresponding to a URL (excluding any style sheets imported recursively),
  2. or, if the style sheet is embedded in HTML, it is the whole HTML file.

6.3.4 The id attribute

The "id" attribute allows authors to assign a unique name to an element. CSS2 allows authors to specify style rules that apply to a single instance of an element, based on its "id" value.

To match an element with a given "id" value, the selector must contain "#" followed by the "id" value.

In the following example, the style rule contains no selector information and therefore matches any element that has id="z98y". The rule will thus match for the P element:

  <HEAD>
  <STYLE>
  #z98y { letter-spacing: 0.3em }
  </STYLE>
  </HEAD>
  <BODY>
  <P id=z98y>Wide text</P>
  </BODY>

In the next example, however, the style rule will only match an H1 element that has id="z98y". The rule will not match the P element in this example:

  <HEAD>
  <STYLE>
  H1#z98y { letter-spacing: 0.5em }
  </STYLE>
  </HEAD>
  <BODY>
  <P id=z98y>Wide text</P>
  </BODY>

Note. While style sheets have been designed to augment document structure, this feature will allow authors to create documents that may render well, but don't take advantage of the structural elements of HTML. This use of style sheets is discouraged.

Note that in HTML 4.0, the ID attribute is called "ID", but in XML documents it may be called something else. The name of the ID attribute is immaterial for CSS. Also note that, even in HTML, the selector #p123 is not equivalent to [ID=p123], since the former has a higher specificity.

6.4 Contextual selectors

At times, authors may want selectors to match elements that appear in a certain context, such as "only those EM elements that are contained by an H1 element". In these cases, contextual selectors  add specificity. Context is defined as an ancestor/descendent relationship between elements in the document tree. Sibling relationships (one element after another) are discussed in the section on sequential selectors.

A contextual selector matches when an element is an arbitrary descendent of some ancestor element (i.e., it may be any generation below the ancestor element). A contextual selector is made up of two or more selectors separated by white space.

For example, consider the following rules:

  H1 { color: red }
  EM { color: red }

Although the intention of these rules is to add emphasis to text by changing its color, the effect will be lost in a case such as:

<H1>This headline is <EM>very</EM> important</H1>

We address this case by adding a contextual rule to the previous two that sets the text color to blue whenever an EM occurs anywhere within an H1:

  H1 { color: red }
  EM { color: red }
  H1 EM { color: blue }

The third rule will also match the following fragment:

  <H1>This 
     <SPAN class="myclass">headline is <EM>very</EM>
     important</SPAN></H1>

A contextual selector may also contain attribute selectors.

For example, the following matches any element with an "href" attribute inside a P with class "myclass" inside any DIV. Note that the space after "myclass" is essential: without it the selector would match a P with both a class and an "href":

DIV P.myclass [href]

Contextual selectors may be grouped according to the rules for grouping listed above.

6.5 Parent-child selectors

A parent-child selector  matches when an element is the direct descendent of some parent element. A parent-child selector is made up of two or more selectors separated by a tilde (~).

The following rule sets the style of P elements that are children of BODY:

  BODY ~ P { line-height: 1.3 }

A parent-child selector may also contain attribute selectors. Parent-child selectors may be grouped according to the rules for grouping listed above.

Contextual selectors and parent-child selectors can be combined. For instance, DIV OL~LI P groups as follows (DIV (OL ~ (LI P))), i.e., it matches a P that is a descendant of an LI, that is in turn a child of an OL, which is a descendant of a DIV.

6.6 Sequential selectors

Often, special formatting rules apply when two types of elements appear next to each other in a document. For example, when block-level elements are laid out, the vertical space between them collapses. In this case, the special formatting is handled by the rules for collapsing margins, but in other cases of sequential selectors, authors may want to specify their own special formatting rules.

Sequential selectors have the following syntax: a forward slash ("/") precedes the first selector and immediately the second selector. The sequential selector matches if the element matched by the first selector precedes the element matched by the second selector, and both have the same parent.

If, in addition, there is a tilde (~) between the selectors, then the sequential selector matches if the element matched by the first selector immediately precedes the element matched by the second selector, i.e., without any intervening elements.

Thus, the following rule states that when a P element immediately follows a MATH element, it should not be indented:

  /MATH ~ P/ { text-indent: 0 } 

The next example brings an H2 that follows an H1 closer to it:

  /H1~H2/ { margin-top: -5mm }   

Sequential selectors may be used along with other types of selectors.

Thus, for example, the following rule is similar to the one in the previous example, except that the special formatting only occurs when H1 has class="opener" (see the section on attribute selectors):

  /H1.opener ~ H2/ { margin-top: -5mm }   

Sequential selectors can also be used to match the first child of some element. In this case the first selector is omitted, and the first slash is doubled, e.g., //P/.

Some descriptions of SGML and XML refer to text data as a "PCDATA element" or a "character-data pseudo-element". For CSS, text is never counted as an element. E.g., the EM in <P>abc <EM>def</EM> is the first child of the P.

The following rule sets the font weight to "bold" for any EM element that is the descendent of a paragraph that is the first child in some element. Note that in this rule, the sequential selector "//P/" is the parent of "EM":

  //P/ EM { font-weight : bold }

Similarly, the following rule suppresses indentation for the first paragraph (P) of a DIV:

  DIV ~ //P/ { text-indent: 0 }

This example would match the P inside the DIV of the following fragment:

  <P> The last P before the note.
  <DIV class="note">
  <P> The first P inside the note.
  </DIV>

but would not match the second P in the following fragment:

  <P> The last P before the note.
  <DIV class="note">
  <H2>Note</H2>
  <P> The first P inside the note.
  </DIV>

[Do we need the functionality of /H1 P/, or only that of /H1~P/ and //P/? Also, should /P// and //P// be added?]

Sequential selectors can be combined with other kinds of selectors: type selectors and attribute selectors can occur inside the slashes, and sequential selectors themselves can be part of contextual or parent-child selectors.

6.7 Pseudo-elements and pseudo-classes

In CSS2, style is normally attached to an element based on its position in the document tree. This simple model is sufficient for many cases, but some common publishing scenarios (such as changing the font size of the first letter of a paragraph) may be independent of the document tree. For instance, in [HTML40], no element refers to the first line of a paragraph, and therefore no simple CSS selector may refer to it.

CSS introduces the concepts of pseudo-elements  and pseudo-classes  to extend the addressing model and permit formatting based on information that lies outside the document tree.

Pseudo-classes are allowed anywhere in selectors while pseudo-elements may only appear as the last segment of a selector.

Although pseudo-elements and pseudo-classes do not exist in the document tree, their behavior is defined as if they did. Each pseudo-element and pseudo-class may be modeled by a fictional tag sequence,  a fragment of document source that includes imaginary elements from the document language. The fictional tag sequence is a tool to describe the rendering effects of pseudo-elements and pseudo-classes and does not indicate how these should be implemented.

Pseudo-elements and pseudo-class names are case-insensitive.

Note. In CSS2, only one pseudo-element can be specified per selector. This may change in future versions of CSS.

Conforming UAs may ignore all rules with :first-line or :first-letter in the selector, or, alternatively, may only support a subset of the properties on these pseudo-elements. See the section on conformance for further information.

6.7.1 The :first-line  pseudo-element

The :first-line pseudo-element is used to apply special styles to the first formatted line. For instance:

  P:first-line { font-style: small-caps }

The above rule means "change the font style of the first line of every paragraph to small-caps". However, the selector "P:first-line" does not match any real HTML element. It does match a pseudo-element that conforming user agents will insert at the beginning of every paragraph.

Note that the length of the first line depends on a number of factors, including the width of the page, the font size, etc. Suppose for this example that the paragraph is broken into the lines indicated in the example. Thus, an ordinary HTML paragraph such as:

  <P>This is a somewhat long HTML paragraph that will
  be broken into several lines. The first line will be
  identified by a fictional tag sequence. The other lines will 
  be treated as ordinary lines in the paragraph.</P>

will be "rewritten" by user agents to include the fictional tag sequence for :first-line.

  <P>
  <P:first-line>This is a somewhat long HTML paragraph that will</P:first-line>
  be broken into several lines. The first line will be
  identified by a fictional tag sequence. The other lines will 
  be treated as ordinary lines in the paragraph.</P>

If a pseudo-element breaks up a real element, the necessary extra tags must be regenerated in the fictional tag sequence. Thus, if we mark up the previous paragraph with a SPAN element:

  <P><SPAN class="test">This is a somewhat long HTML paragraph that will
  be broken into several lines.</SPAN> The first line will be
  identified by a fictional tag sequence. The other lines will 
  be treated as ordinary lines in the paragraph.</P>

The user agent must generate the appropriate start and end tags for SPAN when inserting the fictional tag sequence for :first-line.

  <P><P:first-line><SPAN class="test">This is a somewhat long HTML paragraph that will</SPAN></P:first-line>
  <SPAN>be broken into several lines.</SPAN> The first line will be
  identified by a fictional tag sequence. The other lines will 
  be treated as ordinary lines in the paragraph.</P>

The :first-line  pseudo-element can only be attached to a block-level element.

The :first-line pseudo-element is similar to an inline element, but with certain restrictions. Only the following properties apply to a :first-line element: font properties, color properties, background properties, 'word-spacing', 'letter-spacing', 'text-decoration', 'vertical-align', 'text-transform', 'line-height', and 'clear',

6.7.2 The :first-letter  pseudo-element

[Define better alignment of drop caps? BB]

The :first-letter pseudo-element may be used for "initial caps"  and "drop caps" , which are common typographical effects. It is similar to an inline element if its 'float' property is 'none', otherwise it is similar to a floating element.

These are the properties that apply to :first-letter pseudo-elements: font properties, color properties, background properties, 'text-decoration', 'vertical-align' (only if 'float' is 'none'), 'text-transform', 'line-height', margin properties, padding properties, border properties, 'float', and 'clear'.

The following CSS2 will make a dropcap initial letter span two lines:

<HTML>
 <HEAD>
  <TITLE>Title</TITLE>
  <STYLE type="text/css">
   P              { font-size: 12pt; line-height: 12pt }
   P:first-letter { font-size: 200%; font-style: italic; font-weight: bold; float: left }
   SPAN           { text-transform: uppercase }
  </STYLE>
 </HEAD>
 <BODY>
  <P><SPAN>The first</SPAN> few words of an article in The Economist.</P>
 </BODY>
</HTML>

This example might be formatted as follows:

Image illustrating the combined effect of the :first-letter and :first-line pseudo-elements

The fictional tag sequence  is:

  <P>
  <SPAN>
  <P:first-letter>
  T
  </P:first-letter>he first
  </SPAN> 
  few words of an article in the Economist.
  </P>

Note that the :first-letter pseudo-element tags abut the content (i.e., the initial character), while the :first-line pseudo-element start tag is inserted right after the start tag of the element to which it is attached.

The UA defines what characters are inside the :first-letter element. Quotes that precede the first letter should be included, as in:

Quotes that precede the
first letter should be included.

When the paragraph starts with other punctuation (e.g., parenthesis and ellipsis points) or other characters that are normally not considered letters (e.g., digits and mathematical symbols), :first-letter pseudo-elements are usually ignored.

The :first-letter pseudo-element can only be attached to a block-level element.

Note. Some languages may have specific rules about how to treat certain letter combinations. In Dutch, for example, if the letter combination "ij" appears at the beginning of a word, they should both be considered within the :first-letter pseudo-element.

6.7.3 Overlapping pseudo-elements

Several pseudo-element rules may have an impact on the same content.

In the following example, the first letter of each P element will be green with a font size of 24pt. The rest of the first formatted line will be blue while the rest of the paragraph will be red.

  P { color: red; font-size: 12pt }
  P:first-letter { color: green; font-size: 200% }
  P:first-line { color: blue }

  <P>Some text that ends up on two lines</P>

Assuming that a line break will occur before the word "ends", the fictional tag sequence  for this fragment is:

  <P>
  <P:first-line>
  <P:first-letter> 
  S 
  </P:first-letter>ome text that 
  </P:first-line> 
  ends up on two lines 
  </P>

Note that the :first-letter element is inside the :first-line element. Properties set on :first-line will be inherited by :first-letter, but are overridden if the same property is set on :first-letter.

6.7.4 Pseudo-elements with contextual selectors

In a contextual selector, pseudo-elements are only allowed at the end of the selector.

The following example illustrates this with the :first-letter  pseudo-element.

  BODY P:first-letter { color: purple }

Pseudo-classes may also be used in contextual selectors.

The following example sets the border color to blue of all images that descend from A elements that have not yet been visited:

  A:link IMG { border: solid blue }

6.7.5 Anchor pseudo-classes: :link , :active , and :visited 

User agents commonly display unvisited links differently from previously visited ones. CSS2 allows authors to specify the rendering of a link in one of several states:

The three states are mutually exclusive.

  A:link { color: red }       /* unvisited links */
  A:active { color: lime }    /* active links    */
  A:visited { color: blue }   /* visited links   */

User agents are not required to reformat a currently displayed document due to anchor pseudo-class transitions. For instance, a style sheet may legally specify that the 'font-size' of an :active link should be larger that a :visited link, but the UA is not required to dynamically reformat the document when the reader selects the :visited link.

In HTML, the following two CSS2 declarations are equivalent and select the same elements:

  A:link { color: red }
  :link { color: red }

6.7.6 Combining pseudo-elements with normal classes

Pseudo-classes can be combined with normal classes. In this case, the class name must precede the pseudo-class name in the selector.

If the following link:

  <A class="external" href="http://out.side/">external link</A>

has been visited, this rule:

  A.external:visited { color: blue }

will cause it to be blue.

Pseudo-elements can also be combined with attribute selectors.

Thus, the following rule:

  P.initial:first-letter { color: red }

would make the first letter of all P elements with "class=initial" such as the following, the color red:

  <P class="initial">First paragraph</A>

Pseudo-elements must be specified at the end of the selector.

6.7.7 Colliding attribute selectors and pseudo-classes

CSS syntax allows the following rules to co-exist:

  A:link { color: red }      /* The :link pseudo-class */
  A.link { color: green }    /* In HTML, class=link */
  A#link { color: blue }     /* In HTML, id=link */

Since a link may have class="link", id="link", and belong to the pseudo-class :link simultaneously (i.e., be unvisited), user agents must resolve the colliding rules. User agents must do so according to the cascading order.