[CSS4 Paged Media] page-break control within an 'avoid' block

Grant, Melinda wrote:
> Michael Day wrote:
>>  Grant, Melinda wrote:
>>> [thinking about features for next Paged Media spec] 
>>> - the 'allow' value for page breaking
>> I actually haven't heard of this one, how does it differ from auto?
> 
> It would provide a 'non-preferred break opportunity'; i.e., if you must break inside this block,
> break here.  It may only apply to page-break-inside; I haven't thought it through in enough
> detail yet.  The problem is that the current spec allows one to break out of a
> 'page-break-inside: avoid' block between line boxes, but not between descendant blocks.  We need
> an escape hatch between blocks.

The thing about 'allow' as you describe it is, it's not at the same priority
level as 'auto'. A break with 'allow' is only allowed if there's no other
break opportunity. A break at 'auto', though, can happen anytime it's nearest
the bottom of the page. Consider:

+------------------+
|                  |                  ~~~~~~~~~~~~~~~~~~
|                  |                  ~~~~~breakable~~~~    A
|                  |                  ~~~~~~content~~~~~
|                  |                  ~~~~~~~~~~~~~~~~~~
|                  |
|      Page        |                  ##################
|                  |                  ####unbreakable###    B
|                  |                  ######content#####
|                  |                  ##################
|                  |                  ##~~~breakable~~##   (C)
|                  |                  ##~~~~content~~~##
+------------------+                  ##################
                                       ##################
                                       ##################
                                       ##################
                                       ##################
                                       ##################

So in this example, we have a page size on the left. On the right, we have
a paragraph of normally-breakable content (A) followed by a block (B) with
page-break-inside: avoid. Inside B there are three blocks, and the middle
block has breakable content: i.e. we don't mind having a break there.

If we ignore the page breaking rules, we get this:

Rendering I

+------------------+
|~~~~~~~~~~~~~~~~~~|
|~~~~~breakable~~~~|
|~~~~~~content~~~~~|
|~~~~~~~~~~~~~~~~~~|
|                  |
|##################|
|####unbreakable###|
|######content#####|
|##################|
|##~~~breakable~~##|
|##~~~~content~~~##|
+------------------+

+------------------+
|##################|
|##################|
|##################|
|##################|
|##################|
|##################|
|                  |
|                  |
|                  |
|                  |
|                  |
+------------------+

The natural page-breaking point for this content is right after paragraph C.


If we apply the restriction from page-break-avoid on B, and pretend C has
no overriding rules, we get this:

Rendering II

+------------------+
|~~~~~~~~~~~~~~~~~~|
|~~~~~breakable~~~~|
|~~~~~~content~~~~~|
|~~~~~~~~~~~~~~~~~~|
|                  |
|                  |
|                  |
|                  |
|                  |
|                  |
|                  |
+------------------+

+------------------+
|##################|
|####unbreakable###|
|######content#####|
|##################|
|##~~~breakable~~##|
|##~~~~content~~~##|
|##################|
|##################|
|##################|
|##################|
|##################|

+------------------+
|##################|
|                  |
|                  |
|                  |
|                  |
|                  |
|                  |
|                  |
|                  |
|                  |
|                  |
+------------------+

The unbreakable block doesn't quite fit on one page.


If we use the page breaking rules and take C as "page-break-inside: auto",
then we get this:

Rendering III

+------------------+
|~~~~~~~~~~~~~~~~~~|
|~~~~~breakable~~~~|
|~~~~~~content~~~~~|
|~~~~~~~~~~~~~~~~~~|
|                  |
|##################|
|####unbreakable###|
|######content#####|
|##################|
|##~~~breakable~~##|
|                  |
+------------------+

+------------------+
|##~~~~content~~~##|
|##################|
|##################|
|##################|
|##################|
|##################|
|##################|
|                  |
|                  |
|                  |
|                  |
+------------------+

because C is allowed to break within itself, but not before or after itself
despite all relevant page-break-after and page-break-before values being 'auto'.
(This rendering IMHO doesn't make much sense; if the para needs to stay with
e.g. a previous heading, there should be some page-break-before/after: avoid
in there.)


If we define the 'allow' value and assign C
    C { page-break-inside: allow; page-break-before: allow; page-break-after: allow; }
we get this:

Rendering IV

+------------------+
|~~~~~~~~~~~~~~~~~~|
|~~~~~breakable~~~~|
|~~~~~~content~~~~~|
|~~~~~~~~~~~~~~~~~~|
|                  |
|                  |
|                  |
|                  |
|                  |
|                  |
|                  |
+------------------+

+------------------+
|##################|
|####unbreakable###|
|######content#####|
|##################|
|##~~~breakable~~##|
|##~~~~content~~~##|
|                  |
|                  |
|                  |
|                  |
|                  |
+------------------+

+------------------+
|##################|
|##################|
|##################|
|##################|
|##################|
|##################|
|                  |
|                  |
|                  |
|                  |
|                  |
+------------------+

Which in some cases may be what we want, but what if we wanted Rendering I?
There's still no way to get that without changing the markup.

David Baron had a clever proposal, which said that a page break is allowed
between blocks when inside a page-break-inside: avoid; block iff:
   - all relevant page-break-before and page-break-after values are 'auto'
   - at least one of the three (before, after, and parent) relevant
     page-break-inside values is not 'avoid'
which would make possible all the renderings listed here -- but that proposal
was rejected last March.

Another alternative is to introduce two keywords instead of one:
   'allow' -- page breaks are allowed here. Equivalent to 'auto' on
              page-break-inside, but overrides a parent "page-break-inside:
              avoid" when set on page-break-before or page-break-after.
   'accept' -- page breaks are allowed here only if there's no way to fit the
              whole 'avoid' block on one page.

I personally would have liked to see both... :)

~fantasai

Received on Saturday, 29 September 2007 13:33:45 UTC