W3C home > Mailing lists > Public > www-style@w3.org > July 2008

Re: [CSS2.1] Grammar for @media versus general block parsing

From: Bert Bos <bert@w3.org>
Date: Wed, 2 Jul 2008 21:17:09 +0200
To: "www-style@w3.org" <www-style@w3.org>
Message-Id: <200807022117.09691.bert@w3.org>

On Wednesday 25 June 2008 09:38, Bjoern Hoehrmann wrote:
> * Justin Rogers wrote:
> >Supporting such a feature in CSS 3 won't be a problem. The
> > consideration here is how a CSS 2.1 standards compliant parsing
> > engine should treat the rule given the current wording of the
> > specification.

Here is my analysis (with proposals):

First, I checked if

    @media all {
      @import url(foo.css);
      DIV { color: red; }
    }

conformed to the generic, forward-compatible grammar. It does. So it is 
in principle available for a future extension and therefore must have a 
defined fallback. Björn's examples with {} instead of ; after the 
@-keyword are similarly well-formed.

Björn's remark about @page inside @media in level 3 suggests that we 
intended the @-rule to be ignored, but *not* the DIV rule after it. 
That is also consistent with what happens at the top level, i.e., 
outside of @media, in the case of an erroneous @-rule.

I checked if that behavior could be inferred from the CSS 2.1 spec. It's 
not entirely clear, but the spec *can* be interpreted that way:

Chapter 7, Media Types, says that what is inside @media is a style 
sheet, which implies that anything that can occur at the top level can 
also occur inside @media, unless explicitly forbidden by other 
chapters. In other words: according to chapter 7 on its own, the 
following is fine:

    @media all {
      @import url(foo);
      @page {margin: 0}
      DIV {color: red}
      @media print {
        DIV {color: green}
      }
    }

Looking at the specific rules for @import and @page, we see that there 
are indeed further restrictions. Section 4.1.5, At-rules, says that the 
@import rule must be ignored. I.e., the above is equivalent to

    @media all {
      @page {margin: 0}
      DIV {color: red}
      @media print {
        DIV {color: green}
      }
    }

I didn't actually find any English text that says that the @page and 
@media must be ignored, but the grammar in appendix G claims to be a 
superset of what CSS 2.1 allows, and as the grammar clearly doesn't 
allow @page and @media inside @media, the most reasonable 
interpretation is that those @-rules are to be ignored like the @import 
rule. That leaves

    @media all {
      DIV {color: red}
    }

My conclusion is that CSS 2.1 needs two clarifications:

1) In chapter 13, Paged media, some text has to say in English what is 
currently only implied by the grammar in appendix G, viz., that CSS 
level 2 ignores @page rules that occur inside a block. I propose:

    [Insert in 13.2, just above 13.2.1:] In CSS 2.1, @page rules that
    occur inside any block are ignored. E.g.,

        @media all {
          @page {margin: 0}
          DIV {color: green}
        }

    is equivalent in CSS 2.1 to 

        @media all {
          DIV {color: green}
        }

2) Chapter 7, Media types, similarly needs some text to say explicitly 
that @media in level 2 is only allowed outside of any blocks. E.g.:

    [Insert at the end of 7.2.1:] In CSS 2.1, @media rules that occur
    inside any block are ignored. E.g.,

        @media all {
          @media print {
            DIV {color: red}
          }
          DIV {color: green}
        }

    is equivalent in CSS 2.1 to

        @media all {
          DIV {color: green}
        }

There is an alternative proposal, which might be better in light of the 
fact that those nested @-rules are going to be allowed in level 3. That 
proposal is to add no clarifications, but change the grammar in 
appendix G, with the argument that it is in error, because it forbids 
something that isn't forbidden by any text in the specification. The 
media rule would then become:

    media
      : MEDIA_SYM S* medium [ COMMA S* medium ]*
        LBRACE S* [ ruleset | media | page ]* '}' S*
      ;

A potential practical problem is that it would make current 
implementations that ignore @page inside @media non-conformant and 
would delay CSS 2.1 until we have sufficient implementations again. 
(Unless we promise not to test nested @page for now...)

> I note that most if not all at-rules have similar problems, e.g.,
> @page accepts nested at-rules in CSS Level 3, but CSS 2.1 suggests to
> parse them like the interior of a ruleset, so you get different
> behavior for
>
>   @page { @other { }  margin: 1em } /* versus */
>   @page { @other { }; margin: 1em } /* versus */
>
> Unless the semi-colon is required (the grammar in css3-page suggests
> it is, but the sub-sequent examples do not specify the semi-colon be-
> tween at-rules nested inside @page rules), since you would skip to
> the following ';' at the same {[(-nesting level when parsing a
> ruleset, ala
>
>   p { color: red; @generic-syntax-forbids-this { }; color: green }
>
> (You'd wonder then how to handle @page{@other;;margin:1em) ...).

This seems to be a problem with Paged Media rather than with CSS 2.1, 
but it is certainly one that I hadn't realized before.

CSS 2.1 indeed says that the contents of @page are declarations. And 
thus if CSS level 3 wants to allow margin boxes ('@top-left', etc.) 
inside @page, those will be seen as malformed declarations for the 
purpose of level 2, and will be ignored up to the next semicolon (;), 
not the closing curly brace (}).

The grammar in Paged Media confirms CSS 2.1 in that respect, because it 
requires semicolons to separate the margin boxes. Adding some 
semicolons to fix the examples is easy. But those examples show how 
tempting it is to write them without semicolons...

Is it too late for a different syntax for margin boxes? E.g., rewriting 
example V in 3.5.1:

    @page ::top-left { ... }
    @page ::bottom-center { ... }

    @page :left ::left-middle { ... }
    @page :right ::right-middle { ... }

    @page :left ::bottom-left-corner { ... }
    @page :right ::bottom-right-corner { ... }
    @page :first ::bottom-left-corner { ... }
    @page :first ::bottom-right-corner { ... }

The double colons are not nice, but they do remind one of 
pseudo-elements (just like the single colon in ':first' reminds one of 
pseudo-classes). And they actually avoid a pair of curly braces, which 
is worth something, too.



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, 2 July 2008 19:17:49 GMT

This archive was generated by hypermail 2.2.0+W3C-0.50 : Monday, 27 April 2009 13:55:10 GMT