XML.com: XML From the Inside Out
oreilly.comSafari Bookshelf.Conferences.

advertisement

CSS 3 Selectors
by Russell Dyer | Pages: 1, 2

Implemented CSS3 Selectors

The Mozilla Project has already implemented several CSS3 selectors and is working on implementing the rest soon. The other vendors aren't far behind, either. Let's look at what Mozilla has implemented first.

Three more attribute selectors were added in CSS3; they allow for substring selection. One matches elements based on the beginning values of named attributes. This could be useful, for instance, if one wants to have different styles for hyperlinks to a sub-domain (e.g., sales.somesite.com), as opposed to the main domain (e.g., www.somesite.com):

a[href^='http://sales.']{color: teal;}

To select elements based on the ending value of attributes, the carat above would be replaced with a dollar sign. The rule below would let users know that they are about to click on a link to a Java Server Page.

a[href$='.jsp']{color: purple;}

CSS3 also provides substring matching irrespective of word boundaries. So if one wants to set the border for images from a particular directory (say, /images/artwork/), this rule will accomplish the task:

img[src*='artwork']{
        border-color: #C3B087 #FFF #FFF #C3B087;}

A few more pseudo-class selectors were added in CSS3. One is the :root selector, which allows designers to point to the root element of a document. In HTML, it would be <html>. Since :root is generic, it allows a designer to select the root element of an XML document without necessarily knowing it's name. To permit scrollbars when needed in a document, this rule would work:

:root{overflow:auto;}

As a complement to the :first-child selector, the :last-child was added. With it one can select the last element named of a parent element. For a magazine site with articles contained in <div class='article'></div> tags, where each has a last paragraph with author information, this rule would change the font for each writer's blurb:

div.article > p:last-child{font-style: italic;}

The parent here is a div with article as the class. Once the browser finds such a div tag, it then looks for matching children (<p> tags here). It then selects the last paragraph and adjusts its style based on the rule's declaration.

A new user interaction pseudo-class selector was added: the :target selector. To draw the user's attention to a span of text when the user clicks on a same-page link, a rule like the first line below would work nicely; the link would look like the second line, the highlighted span like the third:

span.notice:target{font-size: 2em; font-style: bold;}
<a href='#section2'>Section 2</a>
<p id='section2'>...</p>

To complement the direct adjacent combinator introduced in CSS2, the indirect adjacent combinator was included in CSS3. It's used in situations where two specified elements are of the same parent and the second element follows the first, but not immediately afterward. To render text as bold when it's contained within <tt> tags, but not when contained within a table, since there will be many elements for the browser to consider (e.g., <tr> and <td> tags) before it would reach a <tt> tag, a direct adjacent combinator selector wouldn't work. But an indirect adjacent combinator selector could handle this:

tt{font-weight:bold;}
table ~ tt{font-weight: normal;}

Finally, a functional notation for selecting specified elements that fail a test has been created. The negation pseudo-class selector (:not) can be coupled with almost any other selector that has been implemented. To put a border around images that don't have a border specified, use a rule like this:

img:not([border]){border: 1;}

Unimplemented CSS3 Selectors

The selectors that are yet to be implemented are a little more complicated but very powerful; they should be implemented soon by the Mozilla Project. Almost all of them are pseudo-class selectors and are very similar. They will likely all be implemented by Mozilla simultaneously.

Quite often designers create online forms for users to complete. As the user fills out portions of a form, based on the user's answers, some portions won't apply. To dynamically style text or input elements based on whether an element is enabled or disabled, the :enabled and :disabled pseudo-class selectors have been devised:

radio.creditcard_type:disabled{color: gray;}

The :checked and :indeterminant pseudo-class selectors were created for styling based on the status of check boxes and radio buttons. To highlight the text associated with a check box once it has been checked, use this rule:

input:checked{background-color: blue; color: white;}

For check boxes and radio buttons that start off with nothing checked, one could highlight them to draw the user's attention to them as required fields. In the example below, the input element has a class label of required:

input.required:indeterminant{color: red;}

Several descendant selectors await implementation. The :only-child selector is used to select elements that don't have any siblings. For instance, if one wants to indent paragraphs for sections (using XML <section> tags) only when there is more than one paragraph, this rule can solve the problem:

section{text-indent: 0.5in;}
section:only-child{text-indent: 0;}

To style based on the uniqueness of type (i.e., no siblings), the :only-of-type selector is available. A related selector is :empty, used for selecting elements that have no children. Use the first rule below to style unique elements in a section and the second for sections with no children:

section:only-of-type{text-style: italic;}
section:empty{text-style: bold;}

Along the same lines, one can style the first and last descendants based on type. Suppose one has several documents (using <doc> tags) that involve the pattern of an introductory paragraph, several main paragraphs, and a concluding paragraph. One could use this rule to style the first and last paragraphs differently:

doc:first-of-type{text-style: bold;}
doc:last-of-type{text-style: italic;}

Keep in mind when using these pseudo-class selectors in which the element type is not specified, that stray elements might be styled unintentionally.

A very handy and potentially confusing set of selectors that have been added in CSS3 are the nth child pseudo-class selectors. These structural selectors were made for designers to be able create precise rules for climbing a document tree. Here's the basic format of an :nth-child selector:

element:nth-child(an+b){...}

The notation a represents the number of children by which the browser is to group. The notation b is the count of each grouping that is selected. The n is always n and is not replaced with a number. To alternate the background of rows in a table, this rule could be deployed in the future:

tr:nth-child(2n+1){background-color: magenta;}

Notice here that the browser is to organize the rows into pairs and to style the first of each pair. To highlight the first of three rows, then this is how the rule would read:

tr:nth-child(3n+1){background-color: tan;}

One could write a rule for each row of the three:

tr:nth-child(3n+1){background-color: tan;}
tr:nth-child(3n+2){background-color: fuschia;}
tr:nth-child(3n+3){background-color: aqua;}

There is some shorthand that can be used. Rather than 2n+1 for odd and 2n+2 for even, they can be replaced with odd and even:

tr:nth-child(odd){background-color: maroon;}
tr:nth-child(even){background-color: tan;}

Incidentally, if a and b are equal, then b can be left out and the value of a will be the implied value of b. The rules below are equivalent and would be applied to the second row of each pair of rows (i.e., the even rows):

tr:nth-child(2n+2){background-color: indigo;}
tr:nth-child(2n){background-color: indigo;}

For a non-repeating pattern, that is, to style one particular element, then the a notation would be set to zero or just left out. The rules below are equivalent and will style just the eighth row:

tr:nth-child(0n+8){background-color: silver;}
tr:nth-child(n+8){background-color: silver;}
tr:nth-child(8){background-color: silver;}

To have the browser count elements starting from the bottom, use the :nth-last-child selector. The a notation uses a negative to indicate a reverse count. This rule styles the last two rows of a table:

tr:nth-last-child(-n+2){background-color: violet;}

To group on types for elements that are mixed with others, use :nth-of-type selector. For instance, suppose one wants to alternate the alignment of images in a document. These rules would do the trick:

img:nth-of-type(2n+1){float: right;}
img:nth-of-type(2n+2){float: left;}

One can count based on type from the bottom, as well, by using the :nth-last-of-type selector. This rule aligns right only the last two images:

img:nth-last-of-type(-n+2){float: right;}

CSS3 also has a content pseudo-class selector. The :contains selector searches the content of a specified element for a matching substring. This selector is for static media only (i.e., print and not screen display). A rule to style text when printed from a bullet list that contains the word "special," would look like this:

li:contains("special"){text-style: italic;}

Finally, to style text differently from the browser's default style that the user selects, the ::selection pseudo-element selector can be used. Typically, when text is selected by a user for copying, the background color changes to blue or black. This rule will alter the user selected text and limit alterations to text within paragraph tags:

p::selection{
        background-color: maroon; font-size: 200%;}

Since this is a pseudo-element selector, only the selected text will be changed while selected and not the entire paragraph.

Concluding Admissions

Although I have attempted to cover all CSS selectors and give examples of each, there are some twists and aspects that I omitted. For instance, there are many ways to combine selectors to accomplish tasks. A few of the example rules presented utilize two or more selectors, hinting at such potential complexities. I also didn't discuss the possibility of using different namespaces with selectors. There's also the issue of what to do about browsers that aren't CSS3 compatible, but are CSS2 compatible. What will they ignore and with what will they meddle?

If you would like more details, you can review the Web Consortium's documentation on Selectors. If you would like to test your browser for compatibility, try the Web Consortium's test pages. For more on CSS in general, check out CSS: The Definitive Guide by Eric Meyer.



1 to 3 of 3
  1. Still no way to move backward?
    2005-12-27 21:57:09 bwucke
  2. "Template" Selectors?
    2003-06-19 16:17:54 Jonathan Block
  3. Regular expression selector?
    2003-06-19 12:33:00 Peter Scott
1 to 3 of 3