CSS is a stylesheet language that works great with XML and XHTML (and even HTML). See the official spec for CSS2.
Remember,
These three items must always be CLEANLY SEPARATED.
Stylesheets let you specify fonts, spacing, aural cues, colors, borders, margins, layout positioning, etc. You should never put that kind of stuff in your markup. (Despite the fact that "loose" versions of XHTML, and the old HTML permit presentational markup, you really should avoid it.)
You can define different stylesheets for different media: PCs, handhelds, cellphones, speech output devices, print, etc. all differ widely in resolution, color depth, bandwidth, etc.
Basically, a CSS style sheet consists of a sequence of statements. Each statement is either a ruleset or an at-rule.
Example:
h1 {color: green}
^ ^ ^
| | |
| | +--- value
| |
| +--- property
|
+--- selector
CSS2 has about 120 properties.
More concise representations are possible:
| Instead of... | You can write... |
|---|---|
h1 {font-weight: bold} |
h1, h2, h3 {font-weight: bold} |
h1 {color: green} |
h1 { |
The official spec says
At-rules start with an at-keyword, an '@' character followed immediately by an identifier (for example, '@import', '@page'). An at-rule consists of everything up to and including the next semicolon (;) or the next block, whichever comes first. A CSS user agent that encounters an unrecognized at-rule must ignore the whole of the at-rule and continue parsing after it. CSS2 user agents must ignore any '@import' rule that occurs inside a block or that doesn't precede all rule sets.
Quite a few ways:
Example (from Harold and Means' text):
<?xml-stylesheet type="text/css" href="recipe.css" media="screen"
alternate="no" title="For Web Browsers" charset="US-ASCII"?>
<?xml-stylesheet type="text/css" href="printable_recipe.css" media="print"
alternate="no" title="For Printing" charset="ISO-8859-1"?>
<?xml-stylesheet type="text/css" href="big_recipe.css" media="projection"
alternate="no" title="For presentations" charset="UTF-8"?>
<?xml-stylesheet type="text/css" href="tty_recipe.css" media="tty"
alternate="no" title="For Lynx" charset="US-ASCII"?>
<?xml-stylesheet type="text/css" href="small_recipe.css" media="handheld"
alternate="no" title="For Palm Pilots" charset="US-ASCII"?>
The possible values for media are: screen, tty, tv, projection, handheld, print, braille, aural, all.
Example
<html>
<head>
<title>Another Example</title>
<link rel="stylesheet" type="text/css" href="plain.css" media="screen" />
</head>
<body>
<p>Hello</p>
</body>
</html>
Example
<html>
<head>
<title>Another Example</title>
<style type="text/css">
body {padding: 2em; background: white;}
p {font: 36pt serif}
</style>
</head>
<body>
<p>Hello</p>
</body>
</html>
Use rarely, if at all. Examples:
<h1 style="color:blue; text-align:right">Hello</h1> <div style="position:absolute; z-index:1; left:20px; top:160px; width:150px">
<html>
<head>
<title>Another Example</title>
<style type="text/css">
body {color: green; background: white;}
h1 {color: navy}
</style>
</head>
<body>
<h1>Test</h1>
<p>Here is an <strong>example</strong> of</p>
<ul>
<li>Style sheets</li>
<li>Inheritance of properties</li>
<li>Overriding</li>
</ul>
</body>
</html>

Note: you CAN specify a style sheet with an xml-stylsheet processing instruction AND a link element in the head AND a style element in the head AND use inline styles too! Rules may even appear to conflict. Each rule is given a weight and when several rules apply, the one with the greatest weight takes precedence.
See Section 6 of the spec for details.
Stolen from the official spec:
| Pattern | Meaning |
|---|---|
| * | Matches any element. |
| E | Matches any E element (i.e., an element of type E). |
| E F | Matches any F element that is a descendant of an E element. |
| E > F | Matches any F element that is a child of an element E. |
| E:first-child | Matches element E when E is the first child of its parent. |
| E:link E:visited | Matches element E if E is the source anchor of a hyperlink of which the target is not yet visited (:link) or already visited (:visited). |
| E:active E:hover E:focus | Matches E during certain user actions. |
| E:lang(c) | Matches element of type E if it is in (human) language c (the document language specifies how language is determined). |
| E + F | Matches any F element immediately preceded by an element E. |
| E[foo] | Matches any E element with the "foo" attribute set (whatever the value). |
| E[foo="warning"] | Matches any E element whose "foo" attribute value is exactly equal to "warning". |
| E[foo~="warning"] | Matches any E element whose "foo" attribute value is a list of space-separated values, one of which is exactly equal to "warning". |
| E[lang|="en"] | Matches any E element whose "lang" attribute has a hyphen-separated list of values beginning (from the left) with "en". |
| DIV.warning | HTML only. The same as DIV[class~="warning"]. |
| E#myid | Matches any E element ID equal to "myid". |
Check out the examples in Section 5 of the spec.
h1 {
font-weight: bold;
font-size: 12pt;
line-height: 14pt;
font-family: Helvetica;
font-variant: normal;
font-style: normal;
font-stretch: normal;
font-size-adjust: none
}
h1 { font: bold 12pt/14pt Helvetica }
ol li {list-style: upper-alpha}
ol ol li {list-style: upper-roman}
ol ol ol li {list-style: lower-alpha}
ol ol ol ol li {list-style: decimal}
p { font-vendor: any } /* Invalid prop.: font-vendor */
h1 { font-style: 12pt } /* Invalid value for prop: 12pt */
h1 { rotation: 70minutes } /* 70minutes is not a valid value */
img { float: left here } /* "here" is not a value of 'float' */
img { background: "red" } /* keywords cannot be quoted in CSS2 */
img { border-width: 3 } /* a unit must be specified for length values */
h3, h4 & h5 {color: red } /* & is an invalid token- WHOLE LINE must be ignored */
The actual grammar is in
Appendix D of
the official spec. In addition to the grammar the spec
defines the meanings of the properties and values, what comments
look like (/* ... */), where comments and whitespace
can go, legal characters, lexical issues like specification
of characters with high codepoints, etc.
The spec also metions how user agents must treat errors in stylesheets. Some examples:
identifier
integer
number
length -> ['+' | '-'] number ('em' | 'ex' | 'px' | 'in' | 'cm' | 'pt' | 'pc')
percentage -> number '%'
uri
color
counter
angle -> ['+' | '-'] number
time -> number ('ms' | 's')
frequency
string
border-style -> ('none' | 'hidden' | 'dotted' | 'dashed'
| 'solid' | 'double' | 'groove' | 'ridge'
| 'inset' | 'outset'
border-width -> 'thin' | 'medium' | 'thick' | length
shape ->
family-name -> identifier | string
generic-family -> 'serif' | 'sans-serif' | 'cursive' | 'fantasy' | 'monospace'
absolute-size -> 'xx-small' | 'x-small' | 'small' | 'medium' | 'large'
| 'x-large' | 'xx-large'
relative-size -> 'larger' | 'smaller'
margin-width -> length | percentage | 'auto'
padding-width -> length | percentage
specific-voice -> identifier
generic-voice -> 'male' | 'female' | 'child'
This table stolen from the official spec, but reformatted a bit
| Name | Values | Initial value | Applies to (Default: all) | Inherited? | Percentages (Default: N/A) | Media groups |
|---|---|---|---|---|---|---|
| 'azimuth' | <angle> | [[ left-side | far-left | left | center-left | center | center-right | right | far-right | right-side ] || behind ] | leftwards | rightwards | inherit | center | yes | aural | ||
| 'background' | ['background-color' || 'background-image' || 'background-repeat' || 'background-attachment' || 'background-position'] | inherit | XX | no | allowed on 'background-position' | visual | |
| 'background-attachment' | scroll | fixed | inherit | scroll | no | visual | ||
| 'background-color' | <color> | transparent | inherit | transparent | no | visual | ||
| 'background-image' | <uri> | none | inherit | none | no | visual | ||
| 'background-position' | [ [<percentage> | <length> ]{1,2} | [ [top | center | bottom] || [left | center | right] ] ] | inherit | 0% 0% | block-level and replaced elements | no | refer to the size of the box itself | visual |
| 'background-repeat' | repeat | repeat-x | repeat-y | no-repeat | inherit | repeat | no | visual | ||
| 'border' | [ 'border-width' || 'border-style' || <color> ] | inherit | see individual properties | no | visual | ||
| 'border-collapse' | collapse | separate | inherit | collapse | 'table' and 'inline-table' elements | yes | visual | |
| 'border-color' | <color>{1,4} | transparent | inherit | see individual properties | no | visual | ||
| 'border-spacing' | <length> <length>? | inherit | 0 | 'table' and 'inline-table' elements | yes | visual | |
| 'border-style' | <border-style>{1,4} | inherit | see individual properties | no | visual | ||
| 'border-top' 'border-right' 'border-bottom' 'border-left' | [ 'border-top-width' || 'border-style' || <color> ] | inherit | see individual properties | no | visual | ||
| 'border-top-color' 'border-right-color' 'border-bottom-color' 'border-left-color' | <color> | inherit | the value of the 'color' property | no | visual | ||
| 'border-top-style' 'border-right-style' 'border-bottom-style' 'border-left-style' | <border-style> | inherit | none | no | visual | ||
| 'border-top-width' 'border-right-width' 'border-bottom-width' 'border-left-width' | <border-width> | inherit | medium | no | visual | ||
| 'border-width' | <border-width>{1,4} | inherit | see individual properties | no | visual | ||
| 'bottom' | <length> | <percentage> | auto | inherit | auto | positioned elements | no | refer to height of containing block | visual |
| 'caption-side' | top | bottom | left | right | inherit | top | 'table-caption' elements | yes | visual | |
| 'clear' | none | left | right | both | inherit | none | block-level elements | no | visual | |
| 'clip' | <shape> | auto | inherit | auto | block-level and replaced elements | no | visual | |
| 'color' | <color> | inherit | depends on user agent | yes | visual | ||
| 'content' | [ <string> | <uri> | <counter> | attr(X) | open-quote | close-quote | no-open-quote | no-close-quote ]+ | inherit | empty string | :before and :after pseudo-elements | no | all | |
| 'counter-increment' | [ <identifier> <integer>? ]+ | none | inherit | none | no | all | ||
| 'counter-reset' | [ <identifier> <integer>? ]+ | none | inherit | none | no | all | ||
| 'cue' | [ 'cue-before' || 'cue-after' ] | inherit | XX | no | aural | ||
| 'cue-after' | <uri> | none | inherit | none | no | aural | ||
| 'cue-before' | <uri> | none | inherit | none | no | aural | ||
| 'cursor' | [ [<uri> ,]* [ auto | crosshair | default | pointer | move | e-resize | ne-resize | nw-resize | n-resize | se-resize | sw-resize | s-resize | w-resize| text | wait | help ] ] | inherit | auto | yes | visual, interactive | ||
| 'direction' | ltr | rtl | inherit | ltr | all elements, but see prose | yes | visual | |
| 'display' | inline | block | list-item | run-in | compact | marker | table | inline-table | table-row-group | table-header-group | table-footer-group | table-row | table-column-group | table-column | table-cell | table-caption | none | inherit | inline | no | all | ||
| 'elevation' | <angle> | below | level | above | higher | lower | inherit | level | yes | aural | ||
| 'empty-cells' | show | hide | inherit | show | 'table-cell' elements | yes | visual | |
| 'float' | left | right | none | inherit | none | all but positioned elements and generated content | no | visual | |
| 'font' | [ [ 'font-style' || 'font-variant' || 'font-weight' ]? 'font-size' [ / 'line-height' ]? 'font-family' ] | caption | icon | menu | message-box | small-caption | status-bar | inherit | see individual properties | yes | allowed on 'font-size' and 'line-height' | visual | |
| 'font-family' | [[ <family-name> | <generic-family> ],]* [<family-name> | <generic-family>] | inherit | depends on user agent | yes | visual | ||
| 'font-size' | <absolute-size> | <relative-size> | <length> | <percentage> | inherit | medium | yes, the computed value is inherited | refer to parent element's font size | visual | |
| 'font-size-adjust' | <number> | none | inherit | none | yes | visual | ||
| 'font-stretch' | normal | wider | narrower | ultra-condensed | extra-condensed | condensed | semi-condensed | semi-expanded | expanded | extra-expanded | ultra-expanded | inherit | normal | yes | visual | ||
| 'font-style' | normal | italic | oblique | inherit | normal | yes | visual | ||
| 'font-variant' | normal | small-caps | inherit | normal | yes | visual | ||
| 'font-weight' | normal | bold | bolder | lighter | 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900 | inherit | normal | yes | visual | ||
| 'height' | <length> | <percentage> | auto | inherit | auto | all elements but non-replaced inline elements, table columns, and column groups | no | see prose | visual |
| 'left' | <length> | <percentage> | auto | inherit | auto | positioned elements | no | refer to width of containing block | visual |
| 'letter-spacing' | normal | <length> | inherit | normal | yes | visual | ||
| 'line-height' | normal | <number> | <length> | <percentage> | inherit | normal | yes | refer to the font size of the element itself | visual | |
| 'list-style' | [ 'list-style-type' || 'list-style-position' || 'list-style-image' ] | inherit | XX | elements with 'display: list-item' | yes | visual | |
| 'list-style-image' | <uri> | none | inherit | none | elements with 'display: list-item' | yes | visual | |
| 'list-style-position' | inside | outside | inherit | outside | elements with 'display: list-item' | yes | visual | |
| 'list-style-type' | disc | circle | square | decimal | decimal-leading-zero | lower-roman | upper-roman | lower-greek | lower-alpha | lower-latin | upper-alpha | upper-latin | hebrew | armenian | georgian | cjk-ideographic | hiragana | katakana | hiragana-iroha | katakana-iroha | none | inherit | disc | elements with 'display: list-item' | yes | visual | |
| 'margin' | <margin-width>{1,4} | inherit | XX | no | refer to width of containing block | visual | |
| 'margin-top' 'margin-right' 'margin-bottom' 'margin-left' | <margin-width> | inherit | 0 | no | refer to width of containing block | visual | |
| 'marker-offset' | <length> | auto | inherit | auto | elements with 'display: marker' | no | visual | |
| 'marks' | [ crop || cross ] | none | inherit | none | page context | N/A | visual, paged | |
| 'max-height' | <length> | <percentage> | none | inherit | none | all elements except non-replaced inline elements and table elements | no | refer to height of containing block | visual |
| 'max-width' | <length> | <percentage> | none | inherit | none | all elements except non-replaced inline elements and table elements | no | refer to width of containing block | visual |
| 'min-height' | <length> | <percentage> | inherit | 0 | all elements except non-replaced inline elements and table elements | no | refer to height of containing block | visual |
| 'min-width' | <length> | <percentage> | inherit | UA dependent | all elements except non-replaced inline elements and table elements | no | refer to width of containing block | visual |
| 'orphans' | <integer> | inherit | 2 | block-level elements | yes | visual, paged | |
| 'outline' | [ 'outline-color' || 'outline-style' || 'outline-width' ] | inherit | see individual properties | no | visual, interactive | ||
| 'outline-color' | <color> | invert | inherit | invert | no | visual, interactive | ||
| 'outline-style' | <border-style> | inherit | none | no | visual, interactive | ||
| 'outline-width' | <border-width> | inherit | medium | no | visual, interactive | ||
| 'overflow' | visible | hidden | scroll | auto | inherit | visible | block-level and replaced elements | no | visual | |
| 'padding' | <padding-width>{1,4} | inherit | XX | no | refer to width of containing block | visual | |
| 'padding-top' 'padding-right' 'padding-bottom' 'padding-left' | <padding-width> | inherit | 0 | no | refer to width of containing block | visual | |
| 'page' | <identifier> | auto | auto | block-level elements | yes | visual, paged | |
| 'page-break-after' | auto | always | avoid | left | right | inherit | auto | block-level elements | no | visual, paged | |
| 'page-break-before' | auto | always | avoid | left | right | inherit | auto | block-level elements | no | visual, paged | |
| 'page-break-inside' | avoid | auto | inherit | auto | block-level elements | yes | visual, paged | |
| 'pause' | [ [<time> | <percentage>]{1,2} ] | inherit | depends on user agent | no | see descriptions of 'pause-before' and 'pause-after' | aural | |
| 'pause-after' | <time> | <percentage> | inherit | depends on user agent | no | see prose | aural | |
| 'pause-before' | <time> | <percentage> | inherit | depends on user agent | no | see prose | aural | |
| 'pitch' | <frequency> | x-low | low | medium | high | x-high | inherit | medium | yes | aural | ||
| 'pitch-range' | <number> | inherit | 50 | yes | aural | ||
| 'play-during' | <uri> mix? repeat? | auto | none | inherit | auto | no | aural | ||
| 'position' | static | relative | absolute | fixed | inherit | static | all elements, but not to generated content | no | visual | |
| 'quotes' | [<string> <string>]+ | none | inherit | depends on user agent | yes | visual | ||
| 'richness' | <number> | inherit | 50 | yes | aural | ||
| 'right' | <length> | <percentage> | auto | inherit | auto | positioned elements | no | refer to width of containing block | visual |
| 'size' | <length>{1,2} | auto | portrait | landscape | inherit | auto | the page context | N/A | visual, paged | |
| 'speak' | normal | none | spell-out | inherit | normal | yes | aural | ||
| 'speak-header' | once | always | inherit | once | elements that have table header information | yes | aural | |
| 'speak-numeral' | digits | continuous | inherit | continuous | yes | aural | ||
| 'speak-punctuation' | code | none | inherit | none | yes | aural | ||
| 'speech-rate' | <number> | x-slow | slow | medium | fast | x-fast | faster | slower | inherit | medium | yes | aural | ||
| 'stress' | <number> | inherit | 50 | yes | aural | ||
| 'table-layout' | auto | fixed | inherit | auto | 'table' and 'inline-table' elements | no | visual | |
| 'text-align' | left | right | center | justify | <string> | inherit | depends on user agent and writing direction | block-level elements | yes | visual | |
| 'text-decoration' | none | [ underline || overline || line-through || blink ] | inherit | none | no (see prose) | visual | ||
| 'text-indent' | <length> | <percentage> | inherit | 0 | block-level elements | yes | refer to width of containing block | visual |
| 'text-shadow' | none | [<color> || <length> <length> <length>? ,]* [<color> || <length> <length> <length>?] | inherit | none | no (see prose) | visual | ||
| 'text-transform' | capitalize | uppercase | lowercase | none | inherit | none | yes | visual | ||
| 'top' | <length> | <percentage> | auto | inherit | auto | positioned elements | no | refer to height of containing block | visual |
| 'unicode-bidi' | normal | embed | bidi-override | inherit | normal | all elements, but see prose | no | visual | |
| 'vertical-align' | baseline | sub | super | top | text-top | middle | bottom | text-bottom | <percentage> | <length> | inherit | baseline | inline-level and 'table-cell' elements | no | refer to the 'line-height' of the element itself | visual |
| 'visibility' | visible | hidden | collapse | inherit | inherit | no | visual | ||
| 'voice-family' | [[<specific-voice> | <generic-voice> ],]* [<specific-voice> | <generic-voice> ] | inherit | depends on user agent | yes | aural | ||
| 'volume' | <number> | <percentage> | silent | x-soft | soft | medium | loud | x-loud | inherit | medium | yes | refer to inherited value | aural | |
| 'white-space' | normal | pre | nowrap | inherit | normal | block-level elements | yes | visual | |
| 'widows' | <integer> | inherit | 2 | block-level elements | yes | visual, paged | |
| 'width' | <length> | <percentage> | auto | inherit | auto | all elements but non-replaced inline elements, table rows, and row groups | no | refer to width of containing block | visual |
| 'word-spacing' | normal | <length> | inherit | normal | yes | visual | ||
| 'z-index' | auto | <integer> | inherit | auto | positioned elements | no | visual |
A B - A must occur, followed by B A | B - Exactly one of A or B must occur A || B - One or more of A or B must occur, in any order Precedence: A B | C || D E means [A B] | [C || [D E]]