CSS

CSS is a stylesheet language that works great with XML and XHTML (and even HTML). See the official spec for CSS2.

Motivation

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.

Getting Started

Statements

Basically, a CSS style sheet consists of a sequence of statements. Each statement is either a ruleset or an at-rule.

Rulesets

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}
h2 {font-weight: bold}
h3 (font-weight: bold}
h1, h2, h3 {font-weight: bold}
h1 {color: green}
h1 {text-align: center}
h1 {
  color: green;
  text-align: center;
}

At-rules

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.

Connecting a stylesheet to a document

Quite a few ways:

  1. In "xml-stylesheet" processing instructions in XML.
  2. In a "link" element in an HTML document, or in an XHTML document has is to be read by a HTML user agent.
  3. In a "style" element in XHTML or HTML.
  4. As a "style" attribute in any XHTML or HTML element that allows it. (This is called an "inline style". Use rarely if at all).

xml-stylesheet Processing Instruction

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.

The <link> element

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>

The <style> element

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>

Inline styles

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">

Inheritance

<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>

cssinheritance.gif

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.

Selectors

Stolen from the official spec:

PatternMeaning
*Matches any element.
EMatches any E element (i.e., an element of type E).
E FMatches any F element that is a descendant of an E element.
E > FMatches any F element that is a child of an element E.
E:first-childMatches 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 + FMatches 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.warningHTML only. The same as DIV[class~="warning"].
E#myidMatches any E element ID equal to "myid".

Check out the examples in Section 5 of the spec.

Some more examples

  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}

Style classes

Miscellaneous non-examples

  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 CSS Language

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:

Types

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'

CSS2 Properties

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]]