- 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