CSS 3 Selectors
by Russell Dyer
June 18, 2003
Although the promise of Cascading Style Sheets (CSS) has been wondrous,
the progress has been wanting. As with all W3C standards, there is the lengthy discussion process
conducted by the related working group, then the problem of implementation
by web browser vendors, and finally the unpredictable period of time for
people to update to new versions of their browser. These steps can take a
year or two each. To expedite the process, the CSS working group has
started grouping related features into modules and releasing them
separately, without waiting for completion of all modules. This allows
browser vendors to proceed with implementation of CSS updates with the
confidence that standards won't be changed by the time the full release of
CSS is approved. Ideally the result will be to reduce the process by a
year or more.
One CSS module that is expected shortly to move to Recommended (or
finished) status by the CSS working group is the Selectors module.
Much of it has already
been implemented by some of the browser vendors. The vendors seem very
keen to expedite the Selectors module since it can improve HTML and
XML document design decidedly and for fairly little effort. As CSS grows,
more selectors are adopted, although some can be pruned. This article
will review all currently approved selectors. It will address the
surviving CSS1 and CSS2 selectors in brief and the new CSS3 selectors in
more detail.
Basic Definitions
A cascading style sheet is used to set or change the styles of a
markup document like a web page. Style sheets contain rules that
web browsers follow when loading a web page, an XML document, or any
document written in a compatible markup language. A style sheet rule is
composed of two basic components: a selector and a
declaration. The selector is an identifier of a markup tag. For
example, in HTML, p is the selector for <p> (or
paragraph) tags. Declarations are the style settings that are to be
applied by the browser when it encounters a match in a document for a
selector. There are many different declarations that may be made, but it
is only selectors that concern us here. So when providing examples, I
will focus on selectors and not comment on declarations.
CSS1 Selector Basics
The basic value of a selector is to point to objects or text for which
a designer would like to set the style. For instance, suppose one decided
to set to navy blue the main heading of each web page on a site containing
over a thousand pages. If all of the pages are linked to the same style
sheet and each page's main heading is wrapped in <h1> tags,
then the task would be simple and quick. It would be a matter of merely
inserting into to the style sheet the simple rule below:
h1{color: navy;}
Occasionally designers need to select elements by class or by
unique identifiers. Suppose a web page contains several tables and
the designer wants the background color of some tables to be silver.
Class selectors can be utilized by assigning a class to tables that are to
be colored. One would place the first line below in the style sheet and
start off silver tables in the document like the second line:
table.special{background-color: silver;}
<table class='special'>
To change the style for only one element on a site, an identification
(ID) can be used:
table#unique{background-color: pink;}
<table ID='unique'>
In CSS1 a few pseudo-class selectors were provided for anchor
(<a>) elements: :link, :visited,
:active, :hover, and :focus. These can be used
to change the style of links depending on their state or on user
interaction. Two pseudo-element selectors were also provided: the
::first-letter and the ::first-line selectors are for
styling the first letter and the first line contained between selected
tags. Pseudo-elements are distinguished by two colons and they can affect
partial content, but the declarations of pseudo-class selectors are
applied to all of the content.
A powerful function found in CSS1 is the descendant combinator.
It allows the designer to select markup elements contained within another
specified element. One simply gives the parent element, then a space
followed by the descendant. Don't confuse this syntax with that of
grouping selectors (e.g., h1, h2, h3{...}). This rule will make
the text within <quote> tags italic and green, but only
when inside a paragraph:
p quote{font-style: italic; color: green;}
To style elements contained within elements that are contained within
ancestor elements, that is, to style grandchildren elements, one would use
an asterisk with spaces around it as a combinator:
p * quote{font-style: italic; color: green;}
From these basic selectors, designers have been able to standardize the
styles of markup documents and reduce design and production time
significantly for the last few years. This has been especially critical
for XML developers since XML doesn't have default styling conventions.
CSS2 Selectors
CSS2 offered a universal selector (*) to allow selection of
specified elements of all parents. For instance, this rule will
select TD cells of all tables:
*.td{font-size: 85%;}
CSS2 expanded selectors to include discerning the values of element
attributes. In HTML an image element (<img/>) may contain
attributes like src, alt, align, and
border. One can check if an image tag has a specified attribute.
To set the padding only for images where the border is given, this rule
will suffice:
img[border]{margin: 5px;}
You can also check if a value is contained in a space separated list
contained in an attribute (e.g.,
img[alt~="fish"]{...}). Or one can check the full
value for an exact match:
img[src="logo.gif"]{border: 0;}
CSS2 also expanded descendant selector possibilities. The
pseudo-element selectors ::before and ::after allow one
to add content before and after elements found. If one marked up the text
of a play with XML tags around the dialog to identify a character's lines
(e.g., <romeo>...</romeo>), one could use CSS to add
text before and after each set of lines:
romeo::before{content: "Romeo: \"";}
romeo::after{content: "\"";}
Starting in CSS2, designers can now change the style for the first
child of an element. To double the size of the first letter of the
first paragraph of each section of a document (provided each section is
enclosed in <div class='section'></div> tags), try
this:
div.section:first-child::first-letter{font-size: 200%;}
Notice that the parent is div; section is the class,
not the child. The child is whatever the browser finds first. It will
double the size of the first letter of each child's content.
A child combinator selector was added to be able to style the
content of elements contained within other specified elements. For
example, suppose one wants to set white as the color of hyperlinks inside
of div tags for a certain class because they have a dark
background. This can be accomplished by using a period to combine
div with the class resources and a greater-than sign as a
combinator to combine the pair with a, as shown below:
div.resources > a{color: white;}
Also added in CSS2 was the direct adjacent combinator. For
example, imagine you want to indent all paragraphs in a document except
for ones immediately following a sub-heading (<h2>). The
second rule below shows an h2 selector combined with a p
selector using a plus sign as the combinator to indicate that the
declaration applies only if p immediately follows
h2:
p{text-indent: 0.5in;}
h2 + p{text-indent: 0;}
Finally, consider the language selector. The :lang selector
is for selecting a document of a specific language:
html:lang(en){color: black;}
xml:lang(en){color: gray;}
Similarly, the hreflang attribute of the link element
can be used with the attribute value selector that checks for a value and
the same value followed by a hyphen. The following rule will match French
(fr) and Belgian French (fr-be):
link[hreflang|="fr"]{font-style: italic;}
[1] [2] Next