1
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
5
<TITLE>Grammar of CSS 2.1</TITLE>
6
<link rel="stylesheet" href="style/default.css" type="text/css">
7
<link rel="stylesheet" href="http://www.w3.org/StyleSheets/TR/W3C-CR.css" type="text/css">
8
<link rel="prev" href="propidx.html">
9
<link rel="next" href="leftblank.html">
10
<link rel="contents" href="cover.html#minitoc">
11
<link rel="CSS-properties" href="propidx.html" title="properties">
12
<link rel="index" href="indexlist.html" title="index">
13
<link rel="first" href="cover.html">
17
<p><a href="propidx.html">previous</a>
18
<a href="leftblank.html">next</a>
19
<a href="cover.html#minitoc">contents</a>
20
<a href="propidx.html">properties</a>
21
<a href="indexlist.html">index</a>
25
<H1><a name="q0">Appendix G. Grammar of CSS 2.1</a></H1>
27
<p><strong>Contents</strong>
29
<li class="tocline2"><a href="grammar.html#grammar" class="tocxref">G.1 Grammar</a>
30
<li class="tocline2"><a href="grammar.html#scanner" class="tocxref">G.2 Lexical scanner</a>
31
<li class="tocline2"><a href="grammar.html#tokenizer-diffs" class="tocxref">G.3 Comparison of tokenization in CSS 2.1 and CSS1</a>
35
<P>The grammar below defines the syntax of CSS 2.1. It is in some sense,
36
however, a superset of CSS 2.1 as this specification imposes additional
37
semantic constraints not expressed in this grammar. A conforming UA
38
must also adhere to the <a href="syndata.html#syntax">
39
forward-compatible parsing rules</a>, the selectors notation, the <a
40
href="about.html#property-defs">property and value notation</a>,
41
and the unit notation. However, not all syntactically correct CSS can take
42
effect, since the document language may impose restrictions that are
43
not in CSS, e.g., HTML imposes restrictions on the possible values of
44
the "class" attribute.
46
<h2>G.1 <a name="grammar">Grammar</a></h2>
48
<P> The grammar below is <a name="x0"><span class="index-inst"
49
title="LALR(1)">LALR(1)</span></a> (but note that most UA's should not use it
50
directly, since it doesn't express the <a
51
href="syndata.html#parsing-errors">parsing conventions</a>, only the
52
CSS 2.1 syntax). The format of the productions is optimized for human
53
consumption and some shorthand notation beyond Yacc (see <a href="refs.html#ref-YACC" rel="biblioentry" class="noxref"><span class="normref">[YACC]</span></a>) is
57
<li><strong>*</strong>: 0 or more
58
<li><strong>+</strong>: 1 or more
59
<li><strong>?</strong>: 0 or 1
60
<li><strong>|</strong>: separates alternatives
61
<li><strong>[ ]</strong>: grouping
64
<p>The productions are:
68
: [ CHARSET_SYM STRING ';' ]?
69
[S|CDO|CDC]* [ import [ [CDO|CDC] [S|CDO|CDC] ]* ]*
70
[ [ ruleset | media | page ] [ [CDO|CDC] [S|CDO|CDC] ]* ]*
74
[STRING|URI] S* [ medium [ COMMA S* medium]* ]? ';' S*
77
: MEDIA_SYM S* medium [ COMMA S* medium ]* LBRACE S* ruleset* '}' S*
83
: PAGE_SYM S* pseudo_page?
84
LBRACE S* declaration? [ ';' S* declaration? ]* '}' S*
104
: selector [ COMMA S* selector ]*
105
LBRACE S* declaration? [ ';' S* declaration? ]* '}' S*
107
<a name="x1"><span class="index-inst" title="selector">selector</span></a>
108
: simple_selector [ combinator simple_selector ]*
111
: element_name [ HASH | class | attrib | pseudo ]*
112
| [ HASH | class | attrib | pseudo ]+
121
: '[' S* IDENT S* [ [ '=' | INCLUDES | DASHMATCH ] S*
122
[ IDENT | STRING ] S* ]? ']'
125
: ':' [ IDENT | FUNCTION S* [IDENT S*]? ')' ]
128
: property ':' S* expr prio?
134
: term [ operator? term ]*
138
[ NUMBER S* | PERCENTAGE S* | LENGTH S* | EMS S* | EXS S* | ANGLE S* |
140
| STRING S* | IDENT S* | URI S* | hexcolor | function
143
: FUNCTION S* expr ')' S*
146
* There is a constraint on the <a name="x2"><span class="index-inst" title="color">color</span></a> that it must
147
* have either 3 or 6 hex-digits (i.e., [0-9a-fA-F])
148
* after the "#"; e.g., "#000" is OK, but "#abcd" is not.
155
<h2>G.2 <a name="scanner">Lexical scanner</a></h2>
157
<p> The following is the <a name="x3"><span class="index-def"
158
title="tokenizer">tokenizer</span></a>, written in Flex (see <a href="refs.html#ref-FLEX" rel="biblioentry" class="noxref"><span class="normref">[FLEX]</span></a>)
159
notation. The tokenizer is case-insensitive.
161
<p>The "\377" represents the highest character
162
number that current versions of Flex can deal with (decimal 255). It
163
should be read as "\4177777" (decimal 1114111), which is the highest
164
possible code point in <a name="x4"><span class="index-inst"
165
title="unicode">Unicode</span></a>/<a name="x5"><span class="index-inst"
166
title="iso-10646">ISO-10646</span></a>.
169
%option case-insensitive
173
unicode \\{h}{1,6}(\r\n|[ \t\r\n\f])?
174
escape {unicode}|\\[^\r\n\f0-9a-f]
175
nmstart [_a-z]|{nonascii}|{escape}
176
nmchar [_a-z0-9-]|{nonascii}|{escape}
177
string1 \"([^\n\r\f\\"]|\\{nl}|{escape})*\"
178
string2 \'([^\n\r\f\\']|\\{nl}|{escape})*\'
179
invalid1 \"([^\n\r\f\\"]|\\{nl}|{escape})*
180
invalid2 \'([^\n\r\f\\']|\\{nl}|{escape})*
182
comment \/\*[^*]*\*+([^/*][^*]*\*+)*\/
183
ident -?{nmstart}{nmchar}*
185
num [0-9]+|[0-9]*"."[0-9]+
186
string {string1}|{string2}
187
invalid {invalid1}|{invalid2}
188
url ([!#$%&*-~]|{nonascii}|{escape})*
193
A a|\\0{0,4}(41|61)(\r\n|[ \t\r\n\f])?
194
C c|\\0{0,4}(43|63)(\r\n|[ \t\r\n\f])?
195
D d|\\0{0,4}(44|64)(\r\n|[ \t\r\n\f])?
196
E e|\\0{0,4}(45|65)(\r\n|[ \t\r\n\f])?
197
G g|\\0{0,4}(47|67)(\r\n|[ \t\r\n\f])?|\\g
198
H h|\\0{0,4}(48|68)(\r\n|[ \t\r\n\f])?|\\h
199
I i|\\0{0,4}(49|69)(\r\n|[ \t\r\n\f])?|\\i
200
K k|\\0{0,4}(4b|6b)(\r\n|[ \t\r\n\f])?|\\k
201
L l|\\0{0,4}(4c|6c)(\r\n|[ \t\r\n\f])?|\\l
202
M m|\\0{0,4}(4d|6d)(\r\n|[ \t\r\n\f])?|\\m
203
N n|\\0{0,4}(4e|6e)(\r\n|[ \t\r\n\f])?|\\n
204
O o|\\0{0,4}(4f|6f)(\r\n|[ \t\r\n\f])?|\\o
205
P p|\\0{0,4}(50|70)(\r\n|[ \t\r\n\f])?|\\p
206
R r|\\0{0,4}(52|72)(\r\n|[ \t\r\n\f])?|\\r
207
S s|\\0{0,4}(53|73)(\r\n|[ \t\r\n\f])?|\\s
208
T t|\\0{0,4}(54|74)(\r\n|[ \t\r\n\f])?|\\t
209
U u|\\0{0,4}(55|75)(\r\n|[ \t\r\n\f])?|\\u
210
X x|\\0{0,4}(58|78)(\r\n|[ \t\r\n\f])?|\\x
211
Z z|\\0{0,4}(5a|7a)(\r\n|[ \t\r\n\f])?|\\z
217
\/\*[^*]*\*+([^/*][^*]*\*+)*\/ /* ignore comments */
219
"<!--" {return CDO;}
221
"~=" {return INCLUDES;}
222
"|=" {return DASHMATCH;}
224
{w}"{" {return LBRACE;}
225
{w}"+" {return PLUS;}
226
{w}">" {return GREATER;}
227
{w}"," {return COMMA;}
229
{string} {return STRING;}
230
{invalid} {return INVALID; /* unclosed string */}
232
{ident} {return IDENT;}
234
"#"{name} {return HASH;}
236
@{I}{M}{P}{O}{R}{T} {return IMPORT_SYM;}
237
@{P}{A}{G}{E} {return PAGE_SYM;}
238
@{M}{E}{D}{I}{A} {return MEDIA_SYM;}
239
"@charset " {return CHARSET_SYM;}
241
"!"({w}|{comment})*{I}{M}{P}{O}{R}{T}{A}{N}{T} {return IMPORTANT_SYM;}
243
{num}{E}{M} {return EMS;}
244
{num}{E}{X} {return EXS;}
245
{num}{P}{X} {return LENGTH;}
246
{num}{C}{M} {return LENGTH;}
247
{num}{M}{M} {return LENGTH;}
248
{num}{I}{N} {return LENGTH;}
249
{num}{P}{T} {return LENGTH;}
250
{num}{P}{C} {return LENGTH;}
251
{num}{D}{E}{G} {return ANGLE;}
252
{num}{R}{A}{D} {return ANGLE;}
253
{num}{G}{R}{A}{D} {return ANGLE;}
254
{num}{M}{S} {return TIME;}
255
{num}{S} {return TIME;}
256
{num}{H}{Z} {return FREQ;}
257
{num}{K}{H}{Z} {return FREQ;}
258
{num}{ident} {return DIMENSION;}
260
{num}% {return PERCENTAGE;}
261
{num} {return NUMBER;}
263
{U}{R}{L}"("{w}{string}{w}")" {return URI;}
264
{U}{R}{L}"("{w}{url}{w}")" {return URI;}
266
{ident}"(" {return FUNCTION;}
271
<h2>G.3 <a name="tokenizer-diffs">Comparison of tokenization in CSS 2.1 and
274
<p>There are some differences in the syntax specified in the CSS1
275
recommendation (<a href="refs.html#ref-CSS1" rel="biblioentry" class="noxref"><span class="informref">[CSS1]</span></a>), and the one above. Most of these are due
276
to new tokens in CSS2 that didn't exist in CSS1. Others are because
277
the grammar has been rewritten to be more readable. However, there are
278
some incompatible changes, that were felt to be errors in the CSS1
279
syntax. They are explained below.
282
<li>CSS1 style sheets could only be in 1-byte-per-character
283
encodings, such as ASCII and ISO-8859-1. CSS 2.1 has no such
284
limitation. In practice, there was little difficulty in extrapolating
285
the CSS1 tokenizer, and some UAs have accepted 2-byte encodings.
287
<li>CSS1 only allowed four hex-digits after the backslash (\) to refer
288
to Unicode characters, CSS2 <a
289
href="syndata.html#escaped-characters">allows six</a>. Furthermore,
290
CSS2 allows a white space character to delimit the escape
291
sequence. E.g., according to CSS1, the string "\abcdef" has 3 letters
292
(\abcd, e, and f), according to CSS2 it has only one (\abcdef).
294
<li>The tab character (ASCII 9) was not allowed in strings. However,
295
since strings in CSS1 were only used for font names and for URLs, the
296
only way this can lead to incompatibility between CSS1 and CSS2 is if
297
a style sheet contains a font family that has a tab in its name.
299
<li>Similarly, newlines (<a href="syndata.html#strings">escaped with a
300
backslash</a>) were not allowed in strings in CSS1.
302
<li>CSS2 parses a number immediately followed by an identifier as a
303
DIMENSION token (i.e., an unknown unit), CSS1 parsed it as a number and an
304
identifier. That means that in CSS1, the declaration 'font:
305
10pt/1.2serif' was correct, as was 'font: 10pt/12pt serif'; in CSS2, a
306
space is required before "serif". (Some UAs accepted the first
307
example, but not the second.)
309
<li>In CSS1, a class name could start with a digit (".55ft"), unless
310
it was a dimension (".55in"). In CSS2, such classes are parsed as
311
unknown dimensions (to allow for future additions of new units). To
312
make ".55ft" a valid class, CSS2 requires the first digit to be
320
<p><a href="propidx.html">previous</a>
321
<a href="leftblank.html">next</a>
322
<a href="cover.html#minitoc">contents</a>
323
<a href="propidx.html">properties</a>
324
<a href="indexlist.html">index</a>