Dr. Dobb's is part of the Informa Tech Division of Informa PLC

This site is operated by a business or businesses owned by Informa PLC and all copyright resides with them. Informa PLC's registered office is 5 Howick Place, London SW1P 1WG. Registered in England and Wales. Number 8860726.


Channels ▼
RSS

Web Development

A Quick Tour of CSS2


Now that the CSS2 specification has become a W3C recommendation, there is a great deal to learn. Web Review's CSS guru, Eric Meyer, reported on many of these changes in a February 1998 article. Since then, however, there have been many changes to the specification. Thus, we present now an updated version of A Quick Tour of CSS.

You're no doubt aware that Cascading Style Sheets (CSS) are a developing web technology that promises a great deal in the way of web page presentation. Browser authors are still working to implement Cascading Style Sheets, level 1 (CSS1), and they seem to get closer with each new version.

Meanwhile, never content to rest on its accomplishments, the CSS&FP Working Group of the World Wide Web Consortium (W3C) has published the next level of style sheets. Logically enough, this standard is called Cascading Style Sheets, level 2 (CSS2). Illogically enough, both Navigator and Internet Explorer attempt to support some of the things which are new in CSS2, even though they haven't finished implementing CSS1 yet.

So what is new in CSS2? I'm so glad you asked. Let's take a quick tour, shall we?

Additions to CSS1 Properties

Only a few CSS1 properties have gained new values, so let's deal with them right off the bat. The first is display. Now, in addition to block, inline, line-item, and none, we have run-in, compact, and marker, as well as a number of values specific to tables (which we'll get to in a bit).

  • compact has an effect similar to <DL compact> (assuming your browser supports that bit of HTML). Basically, if an element is set to {display: compact;}, then it will appear in the margin of the next element, assuming there is enough room for it. Otherwise, the elements will be treated as block-level elements. Think of a "compacted" element as one which is floated, but only if there is room for it to be displayed without altering the formatting of the following element.
  • run-in, on the other hand, has the effect of turning an element into an inline element at the beginning of the following element. Confused yet? This should make it simple:

<H4 style="display: run-in;">A Heading.</H4>
<P>This is a paragraph of text....</P>

The result will look something like this:

A Heading. This is a paragraph of text which has a run-in heading at its beginning. It doesn't look like an H4, does it?

However, this should only work if the next element is block-level, and is not floating or positioned absolutely (more on that in a bit). So, for example, if you try to set a list item to run-in, and the next element is another list item, the items shouldn't run together.

  • marker is used to define an element as being a marker, such as a bullet in an unordered list or a number in an ordered list. This doesn't get used terribly often, but it does hook up with a new element to control positioning of the markers. We'll cover all that when we talk about generated content, so hold tight.
  • As part of the internationalization effort by the W3C, list-style-type gained the following values: hebrew, armenian, georgian, cjk-ideographic, hiragana, hiragana-iroha, katakana, and katakana-iroha. These values allow authors to specify that ordered lists will use counting systems other than decimal and Roman. If you don't know what these values mean, you probably don't need to use them; conversely, if you need them, you probably already know which ones you need.
  • font also picked up a few new values: caption, icon, menu, messagebox, smallcaption, and statusbar. The effects these values will have is to apply a font family, size, weight, etc., which matches the computer's settings for such things in its own environment. For example, icons on a Macintosh are typically labelled using 9-point Geneva. Assuming that hasn't been changed by the user, then any font declaration with a value of icon will result in the use of 9-point Geneva for that element.
  • Finally, there is one very important new feature of CSS2: the value inherit. If you were to ask the question, "OK, to which properties did inherit get applied?" the answer would be, "Every last one of them." Before you ask the next question, inherit is used to explicitly declare that a given computed value should be inherited from its parent. In other words, if the font-size for BODY is computed to be 14 points, then the declaration P {font-size: inherit;} would set all paragraph text to 14 points in size.

A Wide Range of Selectors

Perhaps the biggest area of expansion over CSS1 is in selectors. The CSS2 specification contains a number of new selectors, including the ability to include tag attributes (and their values) in the selectors.

For example, A[href] would match any A with an href attribute, regardless of the value of that href.

If, on the other hand, you want to match those elements which have a certain attribute set to a certain value, you can do that as well. Let's say you want to highlight any hyperlink which points to the W3C's home page. You would then declare:

A[href="http://www.w3.org/"] {background-color: yellow;}

This way, no matter how many hyperlinks you have on your page, only those which point to the given URL will be highlighted with a yellow background.

Speaking of referring to class names, some changes have happened there as well. It is possible to set multiple class names on a given element, such as <P class="footnote example reference">. In CSS1, you could only refer to one of these values, such as P.example, which is the same as P[class="example"] in CSS2. Well, in CSS2 you can modify this selector so that the class name must be an exact match, or set it up so that only one of the values has to match. Given the above three-class paragraph, P[class="example"] wouldn't match it, because the values are different (example isn't the same as footnote example reference). On the other hand, P[class~="example"] would match, because this selector has to match only one of the values in the class attribute. The only difference is the tilde character ( ~ ), but what a difference!

Incidentally, class and ID names can now begin with digits, which they couldn't under CSS1. So .1world is legal, although in some cases you'll have to escape out the number, like this: ./5in. This keeps the browser from getting confused about what look like units in the class name.

Here's another one: the "any-child" selector, which is represented with the greater-than sign ( > ). This lets you assign styles to any element which is a direct child of the first element, such as:

DIV.main > OL {margin-left: 1in;}

In this case, any ordered list which is a direct child of the DIV with a class of main, but not an ordered list which is a grandchild (or later) descendant of DIV.main. Thus, an ordered list which is nested inside another list, or found inside a table, would not have a one-inch left margin as a result of the above rule.

Another interesting selector is the "immediately-follows" selector, which is a plus sign ( + ). Using this, you can set up a style for any element which immediately follows the first element. As an example:

H1 + P {margin-top: 0;}

With this rule, you state that any time a paragraph is the next element after an H1, then that paragraph has a top margin of zero. Any other element will not match this rule, even paragraphs which occur after an H1, although not immediately after it. Here's a quick breakdown:

Will match: Will not match:
<H1>H-1</H1>
<P>para-1</P>
<H1>H-1</H1>
<OL>list-1</OL>
<H1>H-1</H1>
<H2>H-2</H2>
<P>para-1</P>

Just in case you find these a little too limiting for your purposes, there is a universal selector now, which is the asterisk (*). This lets you set styles on a whole range of elements, while sort of bypassing the inheritance mechanism. For example:

* {color: black;}

is the same as listing every element in the document in a grouped selector, and then assigning the color black to them. It can also be used in conjunction with the other selectors, like this:

H1 + * {margin-top: 0;}

This will cause any element following an H1 to have no top margin, no matter what element follows the H1. Therefore, all of the examples given in the "Will match/Will not match" table above would match this rule, since the element following the H1 doesn't matter.

Finally, there is the language selector, which works like this:

P[lang|="en"] {text-align: left;}

This will match any paragraph whose lang attribute has en (English) as one of its values. This is most useful when defining styles for a document which has multiple languages.

You can also string all of these selectors together to create some highly specific criteria for applying styles. Given the large number of combinations and the complexity this introduces, however, I'll have to leave that subject for a future article.

New Pseudo-Classes and -Elements

Joining such famous (and unimplemented) pseudo-elements as :first-letter and :first-line, we have a whole brace of new stuff to talk about.

:hover is intended to affect display of an element while the mouse is over it. For example, you could set anchors to have no underlining, except while the mouse is over the anchor, by declaring A:hover {text-decoration: underline;}. While this is usually done in conjunction with anchors, the specification says you can use it with any element, even things like paragraphs and images. Whether browsers will support this behavior is another story, of course.

Similar to :hover is :focus, but the difference is that :focus is used to apply styles to whatever element is the current focus of input. This might not be the same as the element over which the mouse is hovering. You will most likely see this in forms, where you can use the tab key to move from input field to input field without touching the mouse. You might decide, for example, to change the color of the current form input with:

INPUT:focus {background-color: yellow;}

There are also four new properties which relate to focus: outline-color, outline-style, outline-width, and the shorthand outline. These let you define an outline for a focus element. These are obviously similar to borders, but the difference here is that the outlines can come and go and the focus changes, and they don't cause the document to redraw. They just appear, overwriting anything which may be already there, and then disappear.

  • :first-child is an interesting new pseudo-class. It's used to apply a given style to the first child of an element, which is pretty nifty. Let's say, for example, that you have a document in which all of the paragraphs have a text-indent of half an inch. However, you want the first paragraph of the document to have no indentation of its first line, plus it should have a half-inch left margin and be italicized. You would then declare:

BODY:first-child {text-indent: 0; margin-left: 0.5in; text-style:
italic;}

Thus, the first child element of BODY will have a text indent of 0, plus a left margin of half an inch and italicized text. Remember, though, that this will be applied no matter what element is the first child. If the first child element is an H1, then that H1 will have no text-indent. If it's a paragraph, then that paragraph will have no text-indent.

  • The :lang pseudo-class is used in conjunction with languages, and works something like the |=lang selector we discussed before. In this case, you would declare something like:

P:lang(en) {text-align: left;}

The difference between this and the language selector lies mostly in the syntax. Functionally, they're the same.

Finally, there are the pseudo-properties:

  • :first
  • :left
  • :right
  • :before
  • :after

We'll get to those in the sections on paged media and generated content.

Fun with text and fonts

First, there is text-shadow, which has the effect you'd probably expect from its name: You can define a drop-shadow of a given color for text. You can even set an offset and a blur radius, which means you can get cool fuzzy shadows, or even glow effects, using this property. (I fully expect to see this property heinously abused the instant it's supported by any browser.)

The font section gained two new properties. font-size-adjust is intended to help browsers make sure text will be the intended size, regardless of whether or not the browser can use the font specified in the style sheet. It is often a problem that authors will call for a font that the user doesn't have available, and when another font is substituted, it's either too big or too small to read comfortably. This new property addresses that very problem, and should be very useful for authors who want to make sure that their documents are readable no matter what font gets substituted.

The other new font property is font-stretch. This gives you a range of values which let you stretch the characters in a font horizontally, making them wider or narrower, depending on the value you choose. They range from ultra-condensed to normal (the default), to ultra-expanded, with eight absolute levels, and two relative levels, of stretching all told.

It's also worth mentioning that there is a whole slew of properties that are used to describe, match, and even synthesize fonts. Since it would take a very long article just to explain them all, and most of you wouldn't be interested anyway, I've simply listed them in a sidebar for you to explore on your own if you're interested.


Related Reading


More Insights






Currently we allow the following HTML tags in comments:

Single tags

These tags can be used alone and don't need an ending tag.

<br> Defines a single line break

<hr> Defines a horizontal line

Matching tags

These require an ending tag - e.g. <i>italic text</i>

<a> Defines an anchor

<b> Defines bold text

<big> Defines big text

<blockquote> Defines a long quotation

<caption> Defines a table caption

<cite> Defines a citation

<code> Defines computer code text

<em> Defines emphasized text

<fieldset> Defines a border around elements in a form

<h1> This is heading 1

<h2> This is heading 2

<h3> This is heading 3

<h4> This is heading 4

<h5> This is heading 5

<h6> This is heading 6

<i> Defines italic text

<p> Defines a paragraph

<pre> Defines preformatted text

<q> Defines a short quotation

<samp> Defines sample computer code text

<small> Defines small text

<span> Defines a section in a document

<s> Defines strikethrough text

<strike> Defines strikethrough text

<strong> Defines strong text

<sub> Defines subscripted text

<sup> Defines superscripted text

<u> Defines underlined text

Dr. Dobb's encourages readers to engage in spirited, healthy debate, including taking us to task. However, Dr. Dobb's moderates all comments posted to our site, and reserves the right to modify or remove any content that it determines to be derogatory, offensive, inflammatory, vulgar, irrelevant/off-topic, racist or obvious marketing or spam. Dr. Dobb's further reserves the right to disable the profile of any commenter participating in said activities.

 
Disqus Tips To upload an avatar photo, first complete your Disqus profile. | View the list of supported HTML tags you can use to style comments. | Please read our commenting policy.