- From: Bert Bos <bert@w3.org>
- Date: Wed, 21 Apr 2010 11:35:09 +0200
- To: W3C style mailing list <www-style@w3.org>
(This fulfills my action http://wiki.csswg.org/spec/css2.1#issue-71) Recap of the problem ==================== CSS 2.1 says in section 13.2 that @page is followed by a block of declarations, but the Paged Media module says that it is a mix of declarations and at-rules. Those two conflict. E.g., a UA implementing Paged Media CSS 2.1 must parse a style sheet such as @page { @xyz {abc} margin: 1in } (where @xyz is a future extension) by skipping the unknown at-rule, yielding @page { margin: 1in } A UA following CSS 2.1 must instead skip an invalid declaration, giving: @page {} The following theoretical solutions exist: 1) Change Paged Media to conform to CSS 2.1. That requires that margin boxes (@top, @top-left, etc.) are be declared outside @page, e.g.: @page { margin: 1in } @top { content: "Foo" } ADVANTAGE: This is arguably what Paged Media should have been like, because it matches the style of CSS (which avoids nesting as much as possible) and it fits the generic grammar of CSS (which is designed to mix rulesets and at-rules, not declarations and at-rules). DISADVANTAGE: There are known to be implementations already of the Paged Media module, since it was a CR once. Those implementations appear difficult to change. I know of Prince, PDFReactor, and the HP Deskjet 990 (although I haven't verified that last one myself). 2) Change the error recovery rules for declaration blocks in section 4.2 such that an invalid declaration, if it starts with an at-keyword, is considered to end at a right curly brace as well as at a semicolon. A ruleset such as p {color: green; @x @y {foo} color: red} will then be parsed as p {color: green; color: red} instead of the currently required: p {color: green} DISADVANTAGE: It's rather ugly that different invalid tokens require different recovery strategies. But, more importantly, all known implementations will have to change. Even the UAs that implement the Paged Media module ignore the 'color: red' in the above example. An unknown number of (invalid) style sheets on the Web will change meaning. (Which may affect proprietary extensions as well, e.g., if some software defines a meaning for '@if {cond} color: red'. We don't like proprietary extensions, but we *did* promise this parsing rule as far back as the CR of 2004.) 3) Change CSS 2.1 to conform to the Paged Media module: where it says that @page is followed by a declaration block, say instead that @page is followed by a block with both declarations and at-rules. ADVANTAGE: The existing implementations of Paged Media do not need to change. DISADVANTAGE: UAs that currently follow CSS 2.1 will have to change, viz., by applying a different grammar to @page. However, this only affects style sheets that were already unreliable, because they were parsed differently in different UAs. In June 2009 we decided[1] for option 3, which changed, it seems, a decision of September 2008[2] favoring option 2. Today, option 3 still appears to be the only practical solution, because the cost of option 1 is high and the cost of option 2 even higher. [1] http://www.w3.org/blog/CSS/2009/06/23/resolutions_69 [2] http://www.w3.org/blog/CSS/2008/09/10/resolutions_36 Proposed new text ================= I propose to implement the solution by the following concrete changes to the current CR text of CSS 2.1: a) In section 13.2[3] change > An @page rule consists of the keyword "@page", followed by an > optional page selector, followed by a block of declarations. to | An @page rule consists of the keyword "@page", followed by an | optional page selector, followed by a block containing | declarations and at-rules. b) Optionally, we can add a note: | Note: CSS level 2 has no at-rules that may appear inside | @page, but such at-rules are expected to be defined in level 3. [3] http://www.w3.org/TR/2009/CR-CSS2-20090908/page.html#page-box Furthermore, I suggest the following two enhancements to the text of CSS 2.1: c) In section 4.2[4] in the fifth bullet, change "Invalid at-keywords" to "At-rules with unknown at-keywords". Strictly speaking, this is redundant, but it helps readers. In fact, it is not stated with so many words, but the three bullets for malformed declarations, malformed statements and invalid at-keywords are ordered: an invalid declaration is handled by ignoring just the declaration; any remaining unexpected token in the statement is then handled by ignoring the statement; and finally a statement that is well-formed, but starts with an unknown at-keyword, is also ignored. Applying the bullets in a different order leads to conflicts or to rules that are never applied. My proposed change avoids that readers have to consider those different orders. [4] http://www.w3.org/TR/2009/CR-CSS2-20090908/syndata.html#parsing-errors d) Add explicit error-recovery rules in section 13.2, just above 13.2.1: | The rules for handling malformed declarations, malformed | statements, and invalid at-rules inside @page are as defined in | section 4.2[link], with the following addition: | when the UA expects the start of a declaration or at-rule | (i.e., an IDENT token or an ATKEYWORD token) but finds an | unexpected token instead, that token is considered to be | the first token of a malformed declaration. I.e., the rule for | malformed declarations, rather than malformed statements is used | to determine which tokens to ignore in that case. I'm not sure if this is redundant or not. My guess is that it is not. Bert -- Bert Bos ( W 3 C ) http://www.w3.org/ http://www.w3.org/people/bos W3C/ERCIM bert@w3.org 2004 Rt des Lucioles / BP 93 +33 (0)4 92 38 76 92 06902 Sophia Antipolis Cedex, France
Received on Wednesday, 21 April 2010 09:35:25 UTC