[CSS2.1] [css3-page] page-break-inside inheritance

So the problem is

   Currently page-break-inside: avoids inherits and then takes effect
   as the parent of the break point. This means whether the break should
   be avoided is a simple yes-no problem. This doesn't allow us to express
   nested "keep-together" constraints: i.e. "don't break inside this element,
   but if you have to don't break inside these descendant elements".

the idea is

   * In CSS2.1 make page-break-inside not inherit anymore, but still
     discourage breaks inside its descendants: basically avoid breaking
     at a break point with a page-break-inside: avoid ancestor (rather
     than direct parent). (I believe this was Alex's proposal at some point,
     but we did not understand the negative implications of the current
     behavior when we discussed it.)

   * In CSS3, suggest that the more ancestors with 'avoid' a break
     opportunity has, the more it is to be avoided.

Here are some examples of where we would want to be able to "nest"
page-break-inside avoidance (i.e. the more ancestors with 'avoid' a break
opportunity has, the more it should be avoided):

- An outline structure in which sections should be kept together
   insofar as possible

     I. ---------
        a) ------
           1. ---
           2. ---
           3. ---
        b) ------
           1. ---
           2. ---
     II. --------
        a) ------
           1. ---
           2. ---
        b) ------
     III. -------
        a) ------
           1. ---
           2. ---
        b) ------
        c) ------
           1. ---
           2. ---
           3. ---

   Here with the new rules we can express li { page-break-inside: avoid; }
   and get the primary break points between I/II/III, the secondary breakpoints
   between the a/b/c elements, and tertiary breakpoints between 1/2/3 elements.
   I.e. if the whole thing doesn't fit on one page, but fits on two, we'll get
   a break right before III. And if III doesn't fit on one page by itself, we
   get a break between a.2 and b, not between a.1 and a.2 or somesuch.

   (This is probably the most simple and straightforward example, the next is
   a bit more realistic.)

- Imagine I have a blog. My front page includes 5-10 articles normally. I want
   to keep each article together on one page if possible, but I don't want to
   force breaks between them. Within each article,
     * I want to keep the title and the entire first "hook" paragraph together.
     * I don't care where the breaks are within the body of the article
     * I want to keep the date/attribution/categories/other metadata at the end
       together as one unit.
   With the new rules I can express that as
     article { page-break-inside: avoid; }
     h2      { page-break-after: avoid; }
     p.hook  { page-break-inside: avoid; }
     .meta   { page-break-inside: avoid; }

- Imagine I have a catalog. I have separate sections for Mens, Womens, and Kids
   clothing. I also have a What's New page, where I take some of the top new items
   from each. I present these on one page under Mens, Womens, and Kids headings.
   Each item I present has a name, a picture, a brief description, and a price.
   I want to keep all of this information together in one box: I don't want the
   information to split across pages. I also want to keep each section together
   if possible, but I also want to make sure that if the section breaks it breaks
   between item listings, not between the section title and the first item.
   With the new rules I can do that with
     .item       { page-break-inside: avoid; }
     .section    { page-break-inside: avoid; }
     .section h2 { page-break-after: avoid; }

Ok, so I hope I've given some convincing use cases for this behavior. :)

Now for testing and implementations. Here's my test

It's a multi-page test. According to this test, Opera 9.5 Beta and PrinceXML
both match my proposal for CSS2.1. HP and Epson match the current CSS2.1
spec, but HP strongly supports this change and we already have Epson's
agreement. Microsoft has implemented (but not released) the specced behavior,
says it's very complicated, and supports this change.

Proposed changes to the specs:
   -- 'page-break-inside' no longer inherits
   -- 13.3.3 rule D says
        Rule D: In addition, breaking at (2) is allowed only if the
        'page-break-inside' property is 'auto' <INS> and no ancestor
         has a 'page-break-inside' property of 'avoid'.</INS>

CSS3 Paged Media would also add suggestion: once you know you have to break in
an avoid, try to avoid breaking in places that have more avoids in action. But
since CSS3 Paged Media is closing in on CR, I'd list that as a 'may' just to
open up the possibility and give that as a suggestion. This also lets
implementors experiment with the interaction of page-break-inside: avoid and
page-break-before/after: avoid, which is less straightforward. If for CSS4 we
have a better idea of what rules are good we can start to tighten up on them.


Received on Wednesday, 2 April 2008 03:12:08 UTC