September 11, 2011

CSS Selectors

Have you ever wondered:
  • How many selectors does CSS have?
  • Which selectors come from which version of CSS?
  • How does each selector work?

Me too! so here's what I found out with an example for each one.

CSS 1
E → an element of type E
div

/* selects any div element in the document */
E F → an F element descendant of an E element
div p

/* selects any p element that is a descendant of a div element */
E.warning → an E element whose class is "warning"
.banner

/* selects any element whose class is "banner" */
E#myid → an E element with ID equal to "myid".
#footer

/* selects an element with ID equal to "footer" */
E:link → an E element being the source anchor of a hyperlink of which the target is not yet visited
a:link

/* selects any unvisited a element */
E:visited → an E element being the source anchor of a hyperlink of which the target is already visited
a:visited

/* selects any visited a element */
E:active → an E element currently being selected
a:active

/* selects any a element currently being selected */
E:first-line → the first formatted line of an E element
p:first-line

/* selects the first formatted line of any p element */
E:first-letter → the first formatted letter of an E element
p:first-letter

/* selects the first formatted letter for any p element */
E, F → an element of type E and an element of type F
label, span

/* not really a selector, it's a way of grouping them */
According to the CSS 1 spec: "Anchor pseudo-classes have no effect on elements other than 'A'".

Also, CSS 1 and CSS 2.1 use a single colon to refer to the first-line pseudo-class (:first-line) but CSS 3 uses two colons (::first-line).

CSS 2.1
Includes all previous ones and adds these in:

* → any element
*

/* selects any element */
E > F → an F element child of an E element
div > p

/* selects any p elements that are direct children of a div element */
E:first-child → an E element, first child of its parent
p:first-child

/* selects a p element, the first child of its parent */
E:hover → an E element when it's hovered over
a:hover

/* selects any a element when it's hovered over */
E:focus → an E element while it has the focus
input:focus

/* selects any input element while it has the focus */
E:lang(fr) → an element of type E in language "fr"
*:lang(fr)

/* selects any element which language matches french*/
E[foo] → an E element with a "foo" attribute
img[title]

/* selects any img element with a title attribute */
E + F → an F element immediately preceded by an E element
div + span

/* selects any span element immediately preceded by a sibling div element */
E[foo="bar"] → an E element whose "foo" attribute value is exactly equal to "bar"
p[class="example"]

/* selects any p element whose class attribute is exactly equal to "example" */
E[foo~="bar"] → an E element whose "foo" attribute value is a list of whitespace-separated values, one of which is exactly equal to "bar"
a[title~="copyright"]

/* selects any a element whose title attribute value is a list of
whitespace-separated values, one of which is exactly equal to "copyright" */
E[foo|="en"] → an E element whose "foo" attribute has a hyphen-separated list of values beginning (from the left) with "en"
*[lang|="en"]

/* selects any element whose lang attribute has a hyphen-separated list of
values beginning (from the left) with "en" */

CSS 3
Includes all previous ones and adds these in:

E[foo^="bar"] → an E element whose "foo" attribute value begins exactly with the string "bar"
object[type^="image/"]

/* selects any object element whose type attribute value begins with "image/" */
E[foo$="bar"] → an E element whose "foo" attribute value ends exactly with the string "bar"
a[href$=".html"]

/* selects any a element whose href attribute value ends with ".html" */
E[foo*="bar"] → an E element whose "foo" attribute value contains the substring "bar"
p[title*="hello"]

/* selects any p element whose title attribute value contains the
substring "hello" */
E:root → an E element, root of the document
:root

/* selects the root of the document, i.e. the HTML element */
E:nth-child(n) → an E element, the n-th child of its parent
tr:nth-child(0n+3)

/* selects any tr element that is the third child of its parent */
E:nth-last-child(n) → an E element, the n-th child of its parent, counting from the last one
tr:nth-last-child(-n+2)

/* selects any tr element that is one of the two last rows of an HTML table */
E:nth-of-type(n) → an E element, the n-th sibling of its type
p:nth-of-type(odd)

/* selects any p element with odd position */
E:nth-last-of-type(n) → an E element, the n-th sibling of its type, counting from the last one
p:nth-of-type(even)

/* selects any p element with even position, starting from the last */
E:last-child → an E element, last child of its parent
ol > li:last-child

/* selects any li element which is a last child of an ol element */
E:first-of-type → an E element, first sibling of its type
dt:first-of-type

/* selects any dt element that is the first sibling of its type */
E:last-of-type → an E element, last sibling of its type
td:last-of-type

/* selects any td element that is the last sibling of its type */
E:only-child → an E element, only child of its parent
tr:only-child

/* selects any tr element that is an only child */
E:only-of-type → an E element, only sibling of its type
p:only-of-type

/* selects any p element which is the only of its type in a parent */
E:empty → an E element that has no children (including text nodes)
div:empty

/* selects any empty div element */
E:target → an E element being the target of the referring URI
p:target

/* selects any p element that is the target element of the referring URI */
E:enabled → a user interface element E which is enabled
input:enabled

/* selects any input element that is in a enabled state */
E:disabled → a user interface element E which is disabled
input:disabled

/* selects any input element that is in a disabled state */
E:checked → a user interface element E which is checked
input:checked

/* selects any input element that is selected or is toggled "on" */
E:not(s) → an E element that does not match simple selector s
button:not([disabled])

/* selects all button elements that are not disabled*/
E ~ F → an F element preceded by an E element
div ~ p

/* selects any p element that is a sibling to any div element */

Sources:
Cascading Style Sheets, level 1
Cascading Style Sheets Level 2 Revision 1 (CSS 2.1)
Selectors Level 3