The minimal CSS (i.e., any version of CSS) grammar
that all implementations need to support is defined in section 7 .
The grammar below defines a much smaller language, a language
that defines the syntax of CSS1.
It is in some sense, however, still a superset of
CSS1: there are additional semantic constraints not expressed in
this grammar. A conforming UA must also adhere to the
forward-compatible parsing rules (section 7.1), the property and
value notation (section 5) and the unit notation (section 6). In
addition, HTML imposes restrictions, e.g., on the possible values
of the CLASS attribute.
The grammar below is LL(1) (but note that most UA's
should not use it directly, since it doesn't express the parsing
conventions, only the CSS1 syntax). The format of the productions
is optimized for human consumption and some shorthand notation
beyond yacc [15]
is used:
* : 0 or more
+ : 1 or more
? : 0 or 1
| : separates alternatives
[] : grouping
The productions are:
stylesheet
: [CDO|CDC]* [ import [CDO|CDC]* ]* [ ruleset [CDO|CDC]* ]*
;
import
: IMPORT_SYM [STRING|URL] ';' /* E.g., @import url(fun.css); */
;
unary_operator
: '-' | '+'
;
operator
: '/' | ',' | /* empty */
;
property
: IDENT
;
ruleset
: selector [ ',' selector ]*
'{' declaration [ ';' declaration ]* '}'
;
selector
: simple_selector+ [ pseudo_element | solitary_pseudo_element ]?
| solitary_pseudo_element
;
/* An "id" is an ID that is attached to an element type
** on its left, as in: P#p007
** A "solitary_id" is an ID that is not so attached,
** as in: #p007
** Analogously for classes and pseudo-classes.
*/
simple_selector
: element_name id? class? pseudo_class? /* eg: H1.subject */
| solitary_id class? pseudo_class? /* eg: #xyz33 */
| solitary_class pseudo_class? /* eg: .author */
| solitary_pseudo_class /* eg: :link */
;
element_name
: IDENT
;
pseudo_class /* as in: A:link */
: LINK_PSCLASS_AFTER_IDENT
| VISITED_PSCLASS_AFTER_IDENT
| ACTIVE_PSCLASS_AFTER_IDENT
;
solitary_pseudo_class /* as in: :link */
: LINK_PSCLASS
| VISITED_PSCLASS
| ACTIVE_PSCLASS
;
class /* as in: P.note */
: CLASS_AFTER_IDENT
;
solitary_class /* as in: .note */
: CLASS
;
pseudo_element /* as in: P:first-line */
: FIRST_LETTER_AFTER_IDENT
| FIRST_LINE_AFTER_IDENT
;
solitary_pseudo_element /* as in: :first-line */
: FIRST_LETTER
| FIRST_LINE
;
/* There is a constraint on the id and solitary_id that the
** part after the "#" must be a valid HTML ID value;
** e.g., "#x77" is OK, but "#77" is not.
*/
id
: HASH_AFTER_IDENT
;
solitary_id
: HASH
;
declaration
: property ':' expr prio?
| /* empty */ /* Prevents syntax errors... */
;
prio
: IMPORTANT_SYM /* !important */
;
expr
: term [ operator term ]*
;
term
: unary_operator?
[ NUMBER | STRING | PERCENTAGE | LENGTH | EMS | EXS
| IDENT | hexcolor | URL | RGB ]
;
/* There is a constraint on the color that it must
** have either 3 or 6 hex-digits (i.e., [0-9a-fA-F])
** after the "#"; e.g., "#000" is OK, but "#abcd" is not.
*/
hexcolor
: HASH | HASH_AFTER_IDENT
;
The following is the tokenizer, written in flex [16] notation. Note
that this assumes an 8-bit implementation of flex. The tokenizer
is case-insensitive (flex command line option -i).
HTML documents may contain any of the about 30,000
different characters defined by Unicode. Many documents only need
a few hundred. Many fonts also only contain just a few hundred
glyphs. In combination with section
5.2 , this appendix explains how the
characters in the document and the glyphs in a font are matched.
The content of an HTML document is a sequence of characters
and markup. To send it "over the wire", it is encoded
as a sequence of bytes, using one of several possible encodings.
The HTML document has to be decoded to find the characters. For
example, in Western Europe it is customary to use the byte 224
for an a-with-grave-accent (a), but in Hebrew, it is more common
to use 224 for an Aleph. In Japanese, the meaning of a byte
usually depends on the bytes that preceded it. In some encodings,
one character is encoded as two (or more) bytes.
The UA knows how to decode the bytes by looking at the
"charset" parameter in the HTTP header. Typical
encodings (charset values) are "ASCII" (for English),
"ISO-8859-1" (for Western Europe),
"ISO-8859-8" (for Hebrew), "Shift-JIS" (for
Japanese).
HTML [2][4] , allows some 30,000
different characters, namely those defined by Unicode. Not many
documents will use that many different characters, and choosing
the right encoding will usually ensure that the document only
needs one byte per character. Occasional characters outside the
encoded range can still be entered as numerical character
references: 'Π' will always mean the Greek uppercase Pi,
no matter what encoding was used. Note that this entails that UAs
have to be prepared for any Unicode character, even if they only
handle a few encodings.
A font doesn't contain characters,
it contains pictures of characters, known as glyphs.
The glyphs, in the form of outlines or bitmaps, constitute a
particular representation of a character. Either explicitly or
implicitly, each font has a table associated with it, the font
encoding table, that tells for each glyph
what character it is a representation for. In Type 1 fonts, the
table is referred to as an encoding vector.
In fact, many fonts contain several glyphs for the
same character. Which of those glyphs should be used depends
either on the rules of the language, or on the preference of the
designer.
In Arabic, for example, all letters have four
different shapes, depending on whether the letter is used at the
start of a word, in the middle, at the end, or in isolation. It
is the same character in all cases, and thus there is only one
character in the HTML document, but when printed, it looks
differently each time.
There are also fonts that leave it to the graphic
designer to choose from among various alternative shapes
provided. Unfortunately, CSS1 doesn't yet provide the means to
select those alternatives. Currently, it is always the default
shape that is chosen from such fonts.
To deal with the problem that a single font may not be
enough to display all the characters in a document, or even a
single element, CSS1 allows the use of font
sets.
A font set in CSS1 is a list of fonts, all of the same
style and size, that are tried in sequence to see if they contain
a glyph for a certain character. An element that contains English
text mixed with mathematical symbols may need a font set of two
fonts, one containing letters and digits, the other containing
mathematical symbols. See section
5.2 for a detailed description of the
selection mechanism for font sets.
Here is an example of a font set suitable for a text
that is expected to contain text with Latin characters, Japanese
characters, and mathematical symbols:
BODY { font-family: Baskerville, Mincho, Symbol, serif }
The characters available in the Baskerville font (a
font with only Latin characters) will be taken from that font,
Japanese will be taken from Mincho, and the mathematical symbols
will come from Symbol. Any other characters will (hopefully) come
from the generic font family 'serif'. The 'serif' font family
will also be used if one or more of the other fonts is
unavailable.
See the Gamma
Tutorial in the PNG specification [12] if you aren't
already familiar with gamma issues.
In the computation, UAs displaying on a CRT may assume
an ideal CRT and ignore any effects on apparent gamma caused by
dithering. That means the minimal handling they need to do on
current platforms is:
PC using MS-Windows
none
Unix using X11
none
Mac using QuickDraw
apply gamma 1.39 [13]
(ColorSync-savvy applications may simply pass the sRGB
ICC profile [14]
to ColorSync to perform correct color correction)
SGI using X
apply the gamma value from /etc/config/system.glGammaVal
(the default value being 1.70; applications running on
Irix 6.2 or above may simply pass the sRGB ICC profile to
the color management system)
NeXT using NeXTStep
apply gamma 2.22
"Applying gamma" means that each of the
three R, G and B must be converted to R'=Rgamma,
G'=Ggamma, G'=Bgamma,
before handing to the OS.
This may rapidly be done by building a 256-element
lookup table once per browser invocation thus:
for i := 0 to 255 do
raw := i / 255;
corr := pow (raw, gamma);
table[i] := trunc (0.5 + corr * 255.0)
end
which then avoids any need to do transcendental math
per color attribute, far less per pixel.
The goal of the work on CSS1 has been to create a
simple style sheet mechanism for HTML documents. The current
specification is a balance between the simplicity needed to
realize style sheets on the web, and pressure from authors for
richer visual control. CSS1 offers:
visual markup replacement: HTML extensions, e.g.
"CENTER", "FONT" and
"SPACER", are easily replaced with CSS1 style
sheets.
nicer markup: instead of using "FONT"
elements to achieve the popular small-caps style, one
declaration in the style sheet is sufficient. Compare the
visual markup:
<H1>H<FONT SIZE=-1>EADLINE</FONT></H1>
with the style sheet:
H1 { font-style: small-caps }
<H1>Headline</H1>
various integration levels: CSS1 style rules can
be fetched from external style sheets, included in the
'STYLE' element, or put into 'STYLE' attributes. The
latter option offers easy transition from HTML
extensions.
new effects: some new visual effects have been
added to offer users new toys. The typographical
pseudo-elements and the extra values on the background
property fall into this category.
scalability: CSS1 will be useful on equipment
ranging from text terminals to high-resolution color
workstations. Authors can write one style sheet and be
reasonably sure that the intended style will come across
in the best possible manner.
CSS1 does not offer:
per pixel control: CSS1 values simplicity over
level of control, and although the combination of
background images and styled HTML is powerful, control to
the pixel level is not possible.
author control: the author cannot enforce the use
of a certain sheet, only suggest
a layout language: CSS1 does not offer multiple
columns with text-flow, overlapping frames etc.
a rich query language on the parse tree: CSS1 can
only look for ancestor elements in the parse tree, while
other style sheet languages (e.g. DSSSL [6] ) offers a
full query language.
We expect to see extensions of CSS in several
directions:
paper: better support for printing HTML documents
support for non-visual media: work is in the
process to add a list of properties and corresponding
values to support speech and braille output
color names: the currently supported list may be
extended
fonts: more precise font specification systems
are expected to complement existing CSS1 font properties.
values, properties: we expect vendors to propose
extensions to the CSS1 set of values and properties.
Extending in this direction is trivial for the
specification, but interoperability between different UAs
is a concern
layout language: support for two-dimensional
layout in the tradition of desktop publishing packages.
other DTDs: CSS1 has some HTML-specific parts
(e.g. the special status of the 'CLASS' and 'ID'
attributes) but should easily be extended to apply to
other DTDs as well.