Understanding CSS Selectors

The basic building blocks of a Cascading Style Sheets (CSS) style sheet are its style rules. Selectors are used to "select" elements on an HTML page so that they can be styled. Without selectors, there would be no way to determine how the rules should be applied. This article introduces the fundamentals of CSS declaration syntax, to describe how selectors are used.

This topic contains the following sections.

  • Style Rules
  • Document Tree
  • Selectors and Combinators
  • Pseudo-Classes and Pseudo-Elements
  • Cascading Order and Specificity
  • Selector Support by Version
  • Related topics

Style Rules

A style rule is a statement that tells the browser how to render particular elements on an HTML page. A rule consists of a selector followed by a declaration block. The declaration block is everything between (and including) the curly braces ({}). The following style rule modifies the default rendering of all h1 elements.

selector  declaration block
--------  -----------------------------
h1        { font-variant: small-caps; }
            ------------  ----------
            property      value 

A style declaration consists of a single property-value pair, separated by a colon (:). Extra white space inside a declaration block is ignored, so it can be used to format the rule for increased readability. Multiple declarations are separated by semicolons (;).

Note  Although the semicolon is not required if there is only one declaration, it is a good coding practice to finish the last declaration in a block with a semicolon.

Document Tree

The document tree is the hierarchy of elements encoded in the source HTML. Each level of this tree can be described in terms of its ancestors and descendants. Every element in the tree has exactly one parent (except the root element, which has none) and may possibly have children and/or siblings. Style rules are applied to elements in the document tree based on their element type, relative position in the hierarchy, or attributes such as ID or class.

Selectors and Combinators

A simple selector is either a type or universal (*) selector. A simple selector can be followed immediately by an ID, or classes and/or pseudo-classes, in any order. The style rule is applied when the selector matches an element. The following are samples of simple selectors.

h1              { color:blue; }
#myID           { color: red; }
#myID:hover     { color: orange; }
P.myClass       { color: green; }
P.myClass:hover { text-decoration: underline; }

Simple selectors can be chained together by combinator characters. Combinators specify contextual relationships between simple selectors, such as descendant, child, and adjacent sibling relationships. White space (although a combinator when used by itself) may appear between other combinators and the simple selectors that surround it. The following style rule reduces the amount of space between top-level headings when they appear immediately adjacent to each other in the document tree.

h1 + h2 { margin-top: -5mm; }

To reduce the size of style sheets, multiple selectors can be grouped in comma-separated lists. The comma character itself is not a combinator, but rather a shorthand mechanism used to apply one declaration block to multiple element types.

h1, h2, h3 { font-family: helvetica; }

Note  When grouping selectors, remember that the comma starts an entirely new selector.

Pseudo-Classes and Pseudo-Elements

Style rules are usually attached to an element based on its position in the document structure; however, CSS uses the concepts of pseudo-classes and pseudo-elements to permit formatting based on information that lies outside the document tree. Pseudo-elements are used to address subparts of elements (such as ::first-letter or ::first-line), whereas pseudo-classes classify elements on characteristics other than their name, attributes, or content (such as :first-child, :visited, or :hover). Pseudo-classes are typically dynamic, in the sense that an element can acquire or lose a pseudo-class while a user interacts with the document.

p:first-child:first-line { text-transform: uppercase; }

Note  When combining selector elements, the type selector must always be specified first and the pseudo-element last. The other elements (class, id, and pseudo-class) can appear in any order.

Cascading Order and Specificity

Conflicting rules are inherent to CSS, which allows multiple style sheets to be used on one HTML document. When two or more declarations are applied to the same element, it is possible that there may be a conflict between them. The following algorithm must be followed to determine which rule is finally applied.

  1. Find all declarations that apply, including those that are inherited, for the target @media type.

  2. Sort the declarations by weight and origin. The author's style sheets override the user's custom style sheet (which overrides the default values of the browser), except where the user's declarations are marked as !important. Declarations marked !important carry more weight.

  3. Sort by specificity of selector: selectors with higher specificity override selectors that are more general. Specificity is calculated by concatenating the count of (a) ID attributes, (b) class and pseudo-class attributes, and (c) type names and pseudo-elements in the selector.

    For example, each of the following selectors could apply to a single li element; however, only declarations with the highest specificity are applied in the event of a conflict.

    *             {}  /* a=0 b=0 c=0 -> specificity =   0 */
    li            {}  /* a=0 b=0 c=1 -> specificity =   1 */
    ul li         {}  /* a=0 b=0 c=2 -> specificity =   2 */
    li:first-line {}  /* a=0 b=0 c=2 -> specificity =   2 */
    ul ol+li      {}  /* a=0 b=0 c=3 -> specificity =   3 */
    li.class      {}  /* a=0 b=1 c=1 -> specificity =  11 */
    li#id         {}  /* a=1 b=0 c=1 -> specificity = 101 */ 
    
  4. Sort by order specified: if two rules have the same weight and specificity, the last one parsed wins. (Note that stylesheets specified with an @import rule are parsed first.) Selectors that appear later in the stylesheet will be used if there is any conflict. For this reason, link pseudo-class selectors should always be used in the following order.

    a:link {}
    a:visited {}
    a:hover {}
    a:active {} 
    

Selector Support by Version

The following table lists the selectors that are currently recognized by Windows Internet Explorer and the version in which support was first added.

Simple Selectors Internet Explorer Version
Type, Grouped 3
Class, ID 3
Universal (*) 5.0
Combinators
Descendant ( ) 3
Child (>) 7
Adjacent Sibling (+) 7
Attribute Selectors
Equality [=] 7
Existence [] 7
Hyphen [|=] 7
Prefix [^=] 7
Substring [*=] 7
Suffix [$=] 7
Whitespace [~=] 7
Pseudo-Classes and Pseudo-Elements
:link 3
:visited 3
:hover 4
:active†† 4
::first-letter 5.5
::first-line 5.5
:first-child 7
::after 8
::before 8
:focus 8
:lang(C) 8
:checked 9
@page :first, @page :left, @page :right 9
:root 9
:nth-child(n), :nth-last-child(n), :nth-of-type(n), :nth-last-of-type(n) 9
:first-of-type, :last-of-type, :only-of-type 9
:last-child, :only-child 9
:disabled, :enabled 9
:empty 9
:target 9
:not(s) 9
:enabled, :disabled 9
:checked, :indeterminate 9
:valid, :invalid 10
:required, :optional 10
:-ms-input-placeholder 10

 

† Applicability of :hover was expanded to all elements in Windows Internet Explorer 7.

†† Applicability of :active was expanded to all elements in Windows Internet Explorer 8.

Conceptual

CSS Compatibility in Internet Explorer

CSS Improvements in Internet Explorer 8

Managing Style Sheets

Other Resources

Cascading Style Sheets, Level 2.1 (CSS2.1)

Selectutorial

Selectoracle

The W3C CSS Validation Service