[css3-page] page counters and scope

I had an action item to write a detailed proposal for allowing page-based
counters and document-based counters to interact. The constraints on this
proposal are:

   - It must be precisely and completely defined so that it can be
     interoperably implemented.
   - It must not cause incremental rendering problems. Specifically,
     rendering a page later in the document must not create a counter
     scope that starts before that page. (See dbaron's discussion of
     this problem in
       http://lists.w3.org/Archives/Public/www-style/2008Nov/0024.html
   - It must address the use cases for page-document counter interactions,
     such as a chapter-scoped page counter or a page-scoped footnote counter.

So here's my attempt to define the interaction of page and document counters.

At every page break (including start of document, which corresponds to
start of root element, i.e. immediately before :root::before):

   1. Apply any counter-reset and counter-increment rules to the page box,
      creating and incrementing counters as if all page boxes, including
      this one, were sibling elements in a document. These counters are in
      the @page counter scope, and do not affect content in the document.

   2. Apply all @page resets and increments to all document counters in
      scope at every element break point at the page break. That is, from
      each element that breaks walk up the ancestor chain collecting
      counter scopes. (In CSS3, the UA may instead collect only the
      scopes associated with the latest break in the normal flow of the
      root element.) Then apply all @page-based counter-reset and
      counter-increment declarations as if an element with these
      declarations existed in each counter scope at the exact position
      of the break point in that counter scope.

      (Multiple break points are caused by e.g. floats and tables. When
      multiple columns of content break across the page, each column has
      a break point.)

      Example: Suppose we have two table cells side-by-side. We increment
      counters scoped to the first cell at the point corresponding to the
      breakpoint in that cell, then we increment any counters scoped to
      the second cell, the table row, and all ancestor elements at the
      point corresponding to the breakpoint in the second cell. If multiple
      counter scopes with the same counter name are encountered, they each
      get incremented. (In CSS3, however, the UA is not required to increment
      counters scoped to the first cell at the page break.)

      The effect of @page counter rules at breaks in overflowing content
      is undefined. (This because some implementations print incrementally,
      and can't back up to make counter increments apply to earlier content.)

   3. Copy counters in scope at all break points, in document order,
      into the @page counter scope, obscuring any counters of the same name
      there. (In CSS3, this step is not required.)

   4. Copy counters in scope at the latest break point in the normal
      flow of the root element into the @page counter scope, obscuring any
      counters of the same name there. This ensures that the counters in
      the normal flow preside over counters in e.g. floated elements.

Comments?

~fantasai

Received on Monday, 13 April 2009 21:16:56 UTC