This is the third major revision of the specification. It is on its way from a loose collection of ideas to an Internet-Draft, and we plan to finish by the end of 1995. In this version, the basic parts ("level 1") are approaching stability, and we encourage programmers and authors to start experimenting. We also encourage comments, especially with regard to the separation of levels (is level 1 still too fat?), the naming of properties and values (some have question marks behind), and the idea of using CLASS as selectors. Please send comments to the www-style@w3.org mailing list, or directly to the authors. For background material, see the resource page on HTML style sheets. Last changed: August 10, 1995
HTML is a simple structural document format much used on the World-Wide Web. Web publishers commonly request more influence over the presentation of documents, and HTML is under constant pressure to add visual markup. Allowing publishers to attach style to documents will enhance the aesthetics of the web. Also, style enhances content: some publishers consciously choose colors and fonts based on the message they want to convey.
The web needs a mechanism that allows authors to influence the presentation while preserving the device-independence and document structure of HTML. There are four ways to do this: add new style elements to HTML, add new style attributes to existing HTML elements, resort to other formats (e.g. Postscript, PDF or GIF), or introduce style sheets. The first two alternatives will start a never-ending process of extending HTML to become a presentation language. Also, by not separating style and content they make it hard to apply different styles to the same content. The third alternative offers publishers more control by using presentation-oriented format. Sometimes control is important, but most requests for stylistic influence over text can be satisfied without leaving HTML. We think the fourth alternative, style sheets, is the best way to add style to the web.
Style sheets are very similar to the "templates" of desktop publishing applications. A simple style sheet might suggest that the headlines of a document are rendered in blue on a white background. By attaching style (colors) to the structure of a document (headlines), style sheets ensure device-independence and the preservation of document structure. A style sheet can be stored separately from the document it applies to, and it's easy to change the presentation of a document by applying a different style sheet. Also, one style sheet can be applied to many documents.
HTML is an application of SGML [SGML], and the style sheet mechanism described in this specification is intentionally general enough to apply to any SGML DTD. For reasons of simplicity, all examples apply to HTML. The proposed style sheet mechanism is being developed in conjunction with HTML3 and closely matches its design guidelines.
While style sheets will open for publishers to add style to their
documents, the reader should also be able to influence the
presentation. Sometimes the output device on the reader's side needs
special consideration (helvetica looks terrible on this screen!
),
sometimes personal handicaps requires special consideration (12 pt
helvetica? I havn't been able to read that since I turned 80!
), and
readers may have their own aesthetical preferences (helvetica looks
terrible on any screen
). This proposal is called Cascading
Style Sheets (CSS) for its ability to merge several style sheets from both
readers and authors.
Similarly, the properties have been divided into levels. Level 1 properties include fonts, text and space, but leaves borders and page properties to level 2.
Implementors will also find a formal grammar for level 2.
H1: text-color = blueThe example consists of three parts: selector ("H1"), property ("text-color") and value ("blue"). The selector is the glue between the HTML document and the style, and all HTML elements are possible selectors. HTML elements are defined in the HTML specifications, and the CSS specification only defines a syntax for how to address them. Also, the list of properties and values that can be assigned to elements are defined here. The list of level 1 features has been kept to a to a minimum, while making sure commonly used styles can be expressed.
In order for the style sheet to influence the presentation, the user agent (UA, also known as "web browser" or "web client") must be aware of its existence. This can be done by putting the style sheet inside HTML3's proposed STYLE element, or reference it through a LINK:
<HEAD> <TITLE>Title</TITLE> <STYLE NOTATION=CSS> H1: text-color = blue </STYLE> <LINK rel=StyleSheet href="bill.style"> </HEAD>
Typically, an organization-wide style sheet will reside in one location and be referenced through a LINK. The author may add document-specific style in the STYLE element. If conflicts arise, the hints inside STYLE will override those referenced through LINK.
[There may be several LINKs, in descending order of priority?]
H1, H2, H3: font-family = helveticaSimilarly, assigments can be grouped:
H1: font-size = 12pt, text.leading = 2pt, font-family = helvetica, font-weight = boldThe above exemplified grouping mechanisms are general and can be used with all selectors and assignments. In addition, some properties have their own grouping syntax:
H1: font = 12pt/14pt helvetica boldwhich is equivalent to the previous example.
<H1>The headline <EM>is</EM> important!</H1>Since no color has been assigned to EM, the emphasized "is" will inherit the color of the surrounding element, i.e. it will also appear in blue. Other style properties are likewise inherited, e.g. font family and size.
Inheritance start at the oldest predecessor. In HTML, this is is the "HTML" element (although many HTML authors omit this tag). In order to set a "default" style property, you should use "HTML" as selector:
HTML: text-color = dark-blue -- make dark-blue default
(Note how textual comments start with "--" and run to the end of the line.)
Alternatively, the top-level element can be addressed as "*", e.g.:
*: text-color = dark-blue
Some style properties are not inherited from the parent to the child. In most cases, it is intuitive why this is not the case. E.g., when you set a border around a list (UL, OL, DL), you don't want each list item (LI) to have borders around them.
H1 : text-color = blue EM : text-color = light-blueWhen this style sheet is in effect, all emphasized sections, within or outside H1 will turn light-blue. Probably, you only wanted EMs within H1 to turn light-blue. You can specify this with:
(H1) EM : text-color = light-blue
The selector is now a search pattern. Only the last element of the search pattern is addressed (EM), and only so if the search pattern matches (if EM is inside an H1 element). Note that there may be several generations between EM and H1.
H1: font-family = helvetica H1: font-size = 12pt[describe more features]
A more fancy example includes a drop-cap initial and small-caps text:
<HTML> <HEAD> <TITLE>Title</TITLE> <STYLE NOTATION=CSS> P : text-effect = drop-cap P : font-size = 12pt P : alt-font-size = 24pt -- assuming leading is zero EM : font-style = small-caps </STYLE </HEAD> <BODY> <P><EM>The first</EM> few words of an article in The Economist.. </BODY> </HTML>On an ASCII-device, the above could be formatted as:
___ | HE FIRST few words |of an article in the Economist..The example shows the need for a new generic character-level element in HTML which doesn't bring with it any rendering conventions. We suggest using MARK for this.
Modularity: a style sheet designer can combine several (incomplete) style sheets into one to reduce redundancy:
@import "http://www.style.org/punk.css" H1: text-color = red -- override included sheet
The @import .. statement is semantically equal to a <LINK REL=StyleSheet href= .. >. In case of a conflict, the imported style sheet has lower priority than the one from where it's being imported. [That's why we call in "import", not "include"]
Balance: both readers and authors can influence the presentation through style sheets. To do so, they use the same language and this reflects the philosophy of the web: everyone can become a publisher.
Typically, UAs will assume that the style sheets of your initial page (if it finds any) is your personal favorite, and apply them to all subsequent documents. If subsequent documents have their own style sheets, conflicts may arise. Conflict resolution is based on each style assignment having a weight. By default, the weights of the reader's assignments is less that the weights of the assignments in incoming documents. I.e., if an incoming document has style sheets attached, they will be used even if the reader has personal style sheets. However, the reader can add to the weights of style assignments to make them override the styles of the author:
H1: color = red ! importantAlso, if there are legal reasons behind the author's styles, this can be indicated:
P: font-size = 12pt ! legal "IATA regulations"The description following "! legal" is a warning that should be displayed before being overridden by the reader.
A complete description of the cascading order can be found later in this specification.
<HTML> <HEAD> <TITLE>Title</TITLE> <STYLE NOTATION=CSS> H1.punk: text-color = #00FF00 </STYLE> </HEAD> <BODY> <H1 class = punk>Way too green</H1> </BODY> </HTML>
[The use of the CLASS attribute is under discussion, and the syntax may not be stable yet. One future direction is to allow addressing based on CLASS in level 2]
[How do we deal with multiple classes?]
A{HREF} : text-color = red -- the HREF attribute exists H1{CLASS = huge} : font-size = 60pt -- another way of writing H1.hugeUser agents commonly display newly visited anchors differently from older ones. Ideally, the style sheet mechanism should offer functionality to describe how and when anchors should change. This will be possible with the environment variables of level 2, but for level 1 we need to introduce two pseudo-attributes that can be used for addressing:
A{HREF}{OLD} : text-color = red A{HREF}{NEW} : text-color = blue[Does anyone have a better solution?]
Level 1 contains functionality for addressing elements based on its ancestors. In level 2, one can also address based on siblings. A typical example is making the first paragraph after a headline bold:
/H1/ P: font-weight = boldThe '/' indicates the start of a sequential pattern search. All property assignments are performed on the last element of the search pattern.
Combined with the hierarchical search patterns, one has powerful context-sensitive addressing:
H1 -- every H1 H1, H2 -- every H1 and every H2 (H1) EM -- EM inside H1 (DIV) (H1) EM -- EM inside H1 inside DIV /H1/ P -- P that immediately follows H1 (DIV) /H1/ P -- P that immed. follows H1 inside DIV (DIV) /H1/ (P) EM -- EM inside P that immed. follows H1 inside DIV // P -- P that follows nothing (i.e., P that is 1st child) (DIV{CLASS=CHAP}) P -- P inside DIV with CLASS=CHAP
Could one come up with a simple set of binary conditions to describe an output medium. How about:
[hires & color & bitmap] H1: font-size = 4 [paper] H1: font-size = 24pt [overhead] h1: font-size = 60pt
The following environment variables are available for use in style sheets:
a{href}: text-color = dark-red << $LASTVISIT/30d >> dark-blueThe combination of constraints and environment variables can be quite interesting. Set the left margin to be 1/10 of the window width, but always more than 2em and less than 20em:
html : margin-left = 2em << $WIDTH/10 >> 20emLet the color of the background fade from white to yellow as the document ages. After two days (2d), the fading process is complete:
html : color-background = white << $AGE/2d >> yellowLet the color of text links change from red to blue as the document loads:
html : text-link = red << $FETCHED >> blue
While the main focus of this specification is to define a standard for attaching style to HTML, the users' WWW browsing environment has additional elements. Applications have a user interface, they show you the HTML source on request, and GUI clients have a window size. While one normally would leave user preferences to the application and a configuration file, the notion of cascading style sheets has the potential of addressing all issues of style through one interface. The user's personal style sheet can be used to set the fonts of the browser buttons as well as incoming documents' H1 elements. Authors should be careful when trying to influence environment properties, and clients could choose to ignore them.
It is important to syntactically mark the difference between style properties of the environment and HTML elements. One should be careful when picking names. Here are some possibilities:
$HTML-SOURCE: font-family = courier, font-size = 12pt; $CLIENT-WINDOW: width = 600px, height = 800px; $CLIENT-WINDOW: font-family = helvetica $HTML_ERROR: text-color = yellow, text-background = redAn initial '$' marks environment elements.
@define myred = 0.8, 0.1, 0.1
[Should one define a lexical macro, as in C, or a symbolic constant, as in Pascal?]
[What if "myred" has different definitions in various style sheets?]
Addition, subtraction, multiplication and division are supported.
h2: font-size = h1[font-size] * 0.8 P : font-size = H1.foo[font-size] - 12 ptInstead, one may rephrase expressions in terms of either the inherited property or a symbolic constant. In either case, no special syntax is required:
font-size = font-size - 12pt -- relative to inherited size text-color = myred -- relative to constant
Should one be able to use classes as selectors, i.e., without a GI? People can then introduce new elements without writing new style rules:
<par class=p>This is a <emph class=em>PAR</emph>, which looks like a <tag class=strong>P</tag>, because it is declared as being of of the same class.</par>
This section lists names of settable style properties and their corresponding units. The are grouped for overview purposes only.
This specification suggests a liberal terminology for describing fonts, and a level of detail similar to current desktop publishing applications.
Font sizes can either be set to a certain height using "font-size", or to a relative index using "font-size-index". If defined "font-size" will take priority.
Note that an application may reinterpret an explicit size, depending on the context. E.g., inside a VR scene a font may get a different size because of perspective distortion.
Value: <number> | smallest | smaller | small | normal | large | larger | largest
Initial: normal
Level:
Example: font-size-index = largest
Index 3 corresponds to "normal" (the actual size is application dependent/settable by the user). It is suggested that the expression
font-size-index = font-size-index + 1is equivalent to
font-size = font-size * 1.2[Is there a shorter/better name than font-size-index?]
The value is a prioritized list of font family names and/or generic family names. List items are separated by white space and spaces in font family names are replaced with dashes.
[Do any font names contain '-' ?]
The user agent should stop searching as soon as a font family that fulfills the requirement is found. E.g.:
font.family = serif helveticaIf the user agent finds a "serif" font family, "helvetica" will be disregarded.
Possible generic families:
Where extra-light = -3, light = -2, demi-light = -1, etc.
If the desired weight is not available, the substitution order is undefined.
[the definitions are a bit tricky]
"italic" and "italics" are synonyms.
If "font-family" is defined, "italic" is synonymous with "oblique" and "roman" is synonymous with "upright".
If "font-family" is not defined, "italic" and "roman" will select a "serif" font family, while "oblique" and "upright" will select a "sans-serif" font family.
[Since there always will be some definition of "font-family" (in the end, the UA should have a fallback value), "not defined" should read "not defined at the same weight level". This may be a non-intuitive distinction]
If "small-caps" are not available, capital letter of a smaller font size should be used to render small characters. "small-caps" can be combined with other styles:
H1: font-style = small-caps & italic
"font-leading" refers to the extra space between lines. If a percentage is specified, it is relative to the font size.
[arguably, leading is not a font property but a text property. The main argument for calling it "font-leading" is that it's settable through the "font" shorthand.
This is equivalent to setting font-size, font-leading, font-family, font-style, and font-weight. The shorthand notation takes priority if defined.
[to be consistent with font-leading, perhaps the default spacing should be 0?]
The list of possibilities may be kept short in a first version, it can always be extended later. Formatters should treat unknown values as `box' (a simple rectangle).
"capitalize" uppercases the first character of each word. [define word]
"none" is needed to neutralize the inherited value.
[should capitalized characters be rendered in small-caps or normal capital letters when text-style is "small-caps"? Probably normal]
All rendered using the alternate font/text styled defined with "alt-font" and "alt-text".
alt-font alt-font-family alt-font-size alt-font-leading alt-font-weight alt-font-style alt-text-color alt-text-background alt-text-spacing alt-text-line alt-text-position alt-text-transformNote that alt-text-effect is not a valid property.
This property applies only to elements that are not inline (i.e., that require at least a paragraph break after or before).
Technically, margin properties are not inherited. In practice, margins are inherited since the placement of a rendered element is relative to ancestors and siblings. See the formatting model for more on this.
The vertical space between two blocks of text is the maximum of all bottom margin and top margin specifications between the two. For example, between `abc' and `def' in the fragment "...abc</P></LI></OL><P>def..." the space is the maximum of the bottom margins of P:margin, LI:margin, OL:margin and the top margin of P:margin.
Horizontal margins may be negative.
The vertical space between two blocks of text is the maximum of all bottom margin and top margin specifications between the two. For example, between `abc' and `def' in the fragment "...abc</P></LI></OL><P>def..." the space is the maximum of the bottom margins of P:margin, LI:margin, OL:margin and the top margin of P:margin.
Vertical margins must be positive.
The four widths apply to top, right, bottom and left respectively. If there's only one, it applies to all sides, if there are two or three, the missing widths are taken from the opposite side.
The property is shorthand for setting "margin-top", "margin-right" "margin-bottom" and "margin-left" and separately.
This property is not inherited.
Extra indent to apply to the first line only. May be negative (`outdent'). Only applies if the element starts a paragraph (either because it implies a break itself, or because it happens to follow a break.) An indent is not inserted in the middle of an element that was broken by another (such as BR in HTML).
This property can be applied to text, but it's most useful with inline images and similar insertions. The width is to be enforced by scaling the image if necessary.
Only applies to inline images and other insertions.
For images, the width is to be inforced by scaling the image if necessary.
This property is not inherited. If UL has a border around it, you don't want each LI inside to inherit this border.
Additional possibilities include: single, double, thin-thick, thick-thin, dotted, wavy, baroque, filet, art-deco.
[Perhaps `border' should be changed to `box', because of the proposed box-background (see below) and because it's shorter. Disadvantage is that box-width sounds less natural. I believe both are equally accepted terms in the printing industry.]
A width is either a length or one of the keywords `thin', `medium' or `thick'. The four widths apply to top, right, bottom and left respectively. If there's only one, it applies to all sides, if there are two or three, the missing widths are taken from the opposite side.
The box is drawn inside the space set by margin.*.
How much space to insert between the frame and the text. Again, the order is top, right, bottom, left.
URL must point to an image, which is tiled around the border.
[What should be default: `block' or `inline'? In Panorama, the default is block. Alternative keywords might be `both' for `block' and `none' for `inline'.]
"linebefore" and "lineafter" break the line but ignore margin-top and margin-bottom.
How to display the content. The display-type can be:
Paged and scrolling media should interpret these as best they can, e.g., note could become a footnote.
The string after the keyword is a hint for the label of the button (if any). It follows the syntax of insert-before, so that "note map" causes an button to be inserted with the map entity from the WWW icons.
Replace the element with a rectangle that contains the document that the URL points to. Usually applied to inline images (IMG or FIG).
Numbers can be from -2 to 2, meaning, respectively, no page break allowed, break discouraged, don't care, good breakpoint, forced break. All "page-before" and "page-after" values that apply between two elements are combined according to the following table:
|-2 -1 0 1 2 --+-------------- -2|-2 -2 -2 -2 2 -1|-2 -1 -1 1 2 0|-2 -1 0 1 2 1|-2 1 1 1 2 2| 2 2 2 2 2In algorithmic terms: take the one with the largest absolute value; if they are the same, use the positive value.
Values can be -2, -1, or 0, meaning, respectively, keep on same page, page break discouraged, and don't care.
{Question: maybe this is not the best name for the property.]
Uses altfont. Note that the string can be an expression:
insert.before = caution " class = " {CLASS} 1em
This is a concatenation of a symbol entity `caution', a string, an attribute value and 1em of whitespace.
The concatenation operator is implicit. Keywords in the expression can be either entity names (ISO character entities or WWW symbol entities), properties of type length (such as margin.left), or other properties. Entities are replaced by their symbol, lengths are replaced by that amount of horizontal whitespace, other properties are converted to a string. Sub-expressions of type length are evaluated and converted to that amount of whitespace.
*: numbering = on | off *: number-style = arabic | lowerroman | upperroman | loweralpha | upperalpha *: number-inherit = on|off
[Needs some work, level 2 issue?]
percent (%) -- relative to another length unit inches (in) pixels (px) centimeters (cm) millimeters (mm) ems (em) -- the width of the character 'M' ens (en) -- half the width of an em points (pt) characters (ch) -- should be dropped in favor of ems? picas (pc)
A color is a either a color name, 3-tuple or a hex-color. A short list of supported color names should be added, e.g., black, white, red, green, blue, yellow, cyan, magenta, pink, brown, gray, orange, purple, turquoise, violet. Also, prefixing coler names with "light-" or "dark-" is allowed, e.g. "light-blue" and "dark-gray".
By default, the RGB color model is being used. Other color models should be kept in mind for later extensions.
Different ways to specify red:
EM: text-color = #F00 EM: text-color = #FF0000 EM: text-color = 255 0 0 -- integer range: 0-255 EM: text-color = 1.0 0.0 0.0 -- float range: 0.0 - 1.0 EM: text-color = red
Conflicts are intrinsic to the CSS mechanism. As long as a well-defined conflict resolution method is defined, conflicts enhance the mechanism and should not be avoided. For each style sheet assignment, a weight is computed based on four factors:
[asymmetry is introduced?]
Both readers and authors may use the style sheet language to specify preferences. A possible convention is that style sheets attached to the initial document become the personal preferences of the reader. In most cases the reader will be happy to accept the style hints from the author, but human or technological handicaps may require the overriding of the author's hints. On the other side, authors may face legal requirements on the presentation, e.g. the font size. The priority of the different weights are as follows:
CLASS | DESCRIPTION |
---|---|
reader lens | Interactive control, UA specific |
author legal | E.g.: font-size = 12pt ! "IATA requirement" |
reader important | E.g.: font-size = 12pt ! important |
author default | default for incoming style |
reader default | default for reader's personal style |
UA defaults | UAs should always have fallback values |
The string following "legal" gives an explanation for its use. The client should warn the reader, and display the explanation, when style hints tagged "legal" are overridden and this isn't clear from the context.
Contexts where this should be clear:
One should also keep in mind that:
The style sheet mechanism should be liberal in accepting alternative names, e.g. to shorten the length of a style specification. Also, people come to the web from different platforms and bring with them different vocabularies.
back : background, bg fore : foreground, fg pt : point, points pa : pica, picas etc.
h1: margin 15pt 30pt 10pt 40pt -- top, right, bottom, leftVertically, all boxes are attached to the above box. Note that the above box doesn't necessarily contain the preceding HTML element. See the last example.
Horizontally, boxes inherit the maximum space after the ancestor's margins have been deducted.
In the following examples, border-offset and border-width are assumed to be zero.
The first example shows how an H1 element is followed by a P, and how their margins are added to the ones belonging to BODY:
___________________________________ | | | (BODY margins) | | _____________________________ | | | | | white space = margins | | (H1 margins) | | '.' = white space | | | | ';' = unclaimed territory, | | This.is.the.headline!.. | | | |_____________________________| | | | | | | | (P margins) | | | | | | | | This.is.the.paragraph.. | | | | which.is.used.to.convey | | | | how.elements.are.put.on | | | | top.of.each.other...... | | | |_____________________________| | | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |___________________________________|When nested lists are added, the picture becomes a bit more complicated:
___________________________________ | | | (BODY margins) | | _____________________________ | | | | | | | (UL margins) | | <- first level UL element | | ________________________ | | | | | | | | | | | (LI margins) | | | | | | | | | | | | First.list........ | | | | | |________________________| | | | | | | | | | | | (UL margins) | | | <- second level UL element | | | __________________ | | | | | | | | | | | | | | | (LI margins) | | | | | | | | | | | | | | | | Second.list... | | | | | | | |__________________| | | | | | |________________________| | | | |_____________________________| | | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |___________________________________|Note that the left edge of the second-level UL box ends up being aligned with the above LI box since they both are children of the first-level UL element.
Since boxes are stacked vertically, some interesting effects can be achieved if sequential boxes don't end up on top of each other. In this way, "sideheads" and simple multiple-column layouts can be supported:
__________________________________________ | | | (BODY margins) | | ______________ _____________________ | | | |;| | | | | (H1 margins) |;| (P margins) | | | | |;| | | | | Headline... |;| While.the.paragraph | | | | comes.here. |;| starts.here.and.... | | | |______________|;| continues.below.the | | | ;;;;;;;;;;;;;;;;;| box.to.the.left.... | | | ;;;;;;;;;;;;;;;;;|_____________________| | | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |__________________________________________|The above could be realized through:
h1: margin-left = 10%, margin-right = 60% p: margin-left = 50%, margin-right = 10%The percentages are relative to the width of the canvas
This is a grammar for the Cascading Style Sheets. It consists of two parts: a context free grammar suitable for a LL(1) parser, and a lexical analyzer in Lex format.
The CFG uses brackets ([]) for grouping, a postfix asterisk (*) to mean zero or more, a postfix plus (+) for one or more, a postfix question mark (?) for zero or one, and a vertical bar (|) for separating alternatives.
A style sheet starts with zero or more references to imported style sheets, followed by optional declarations, followed by the style rules themselves.
There are two kinds of declarations: constants and architectural forms. Constant declarations define symbolic constants for use in the right hand side of properties. An architectural form defines which attribute to use as the architectural form, by default this is `CLASS'. Although the syntax allows multiple architectural form declarations, what happens when there is more than one is application dependent.
The `value' in the rhs of a constant declaration follows the same syntax as the value in property specifications (defined below), but it has a restriction in that it must be evaluated context independently, which means in practice that it cannot refer to attributes or values of properties.
The style rules may be divided into sections for different media. The first part refers to all media, after a medium specification, the rules apply only to output on that medium. A medium is something like `[speech]', `[hicolor]' `[monochrome]', etc.
A style rule consists of one or more selectors, a colon, one or more properties, and an optional priority.
An address, if not *, consists of a element name (GI and/or class), optionally followed by attribute specification and optionally preceded by a context.
A context is best viewed from right to left. It can consist of the element's immediate predecessor (elder sibling), and any number of ancestors, each of which can also be prefixed with its immediate predecessor. Ancestors are enclosed in parentheses (), predecessors in slashes //. Predecessors can only be indicated by their GI or class, ancestors can be further qualified by attributes.
A priority consists of an exclamation mark, a keyword, and an optional string. The keyword is redundant, since the presence of the exclamation mark plus the fact if the rule came from a local style sheet or a remote one, completely determines the priority. The optional string is displayed to the user as a warning when the formatter is ignoring the rule for some reason.
A property consists of a name and a value, where the value is actually an expression. Note that the operator between terms can be empty. The empty operator creates a list.
Unfortunately, there is an ambiguity because of this: 7+8 could mean (7) (+8) or (7+8). The parser should use the latter.
The terminals of the grammar above are defined with the following Lex specification.
nmstrt [a-zA-Z] nmchar [a-zA-Z0-9.-] ident {nmstrt}{nmchar}* d [0-9] number {d}+|{d}*\.{d}+ h [0-9a-fA-F] hexcolor #{h}{h}{h}|#{h}{h}{h}{h}{h}{h} w [ \t]* %% "\n" return EOL; <<EOF>> return EOL; "@import" return IMPORT; \"([^"]|\\\")*\" | \'([^']|\\\')*\' return STRING; "@define" return DEFINE; {ident} {yylval.string = yytext; return IDENT;} "@archform" return ARCHFORM; {hexcolor} {yylval.string = yytext; return HEXCOLOR;} {number} {yylval.number = atof(yytext); return NUMBER;} {number}"%" {yylval.number = atof(yytext)/100; return NUMBER;} {number}{w}in | {number}{w}inch {yylval.number = atof(yytext)*INCH; return LENGTH;} {number}{w}cm {yylval.number = atof(yytext)*CM; return LENGTH;} {number}{w}mm {yylval.number = atof(yytext)*MM; return LENGTH;} {number}{w}pica | {number}{w}pc {yylval.number = atof(yytext)*PICA; return LENGTH;} {number}{w}pt {yylval.number = atof(yytext)*POINT; return LENGTH;} {number}{w}px {yylval.number = atof(yytext)*pixel; return LENGTH;} {number}{w}ch {yylval.number = atof(yytext); return NCHARS;} {number}{w}em {yylval.number = atof(yytext); return EMS;} "<<" return INTERPOLATELO; ">>" return INTERPOLATEHI; "+=" return PLUS_EQ; "-=" return MINUS_EQ; "*=" return STAR_EQ; "/=" return SLASH_EQ;[synchornize terminology (rule, term, assignment, hint etc) throughout the document]
During the short life of HTML, there have been several style sheet proposals to which this proposal is indebted. The following people's proposals have been very influential: