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

This is sitting in my list of things to read and understand for a while... Now that I am cleaning up my to do list before end of the year, I have read and understood;)

Fantasai, thanks for a detailed explanation. Yes, apparently there are ways to define 'allow' and 'auto' to do different things.

I am not sure I agree with rendering IV. If there isn't a forced break between A and B, there shouldn't be a break there (because there is a break opportunity in C). Having non-forced breaks have priorities would really complicate the model...

Overall I would approach this with a goal of simpler model first. If we can define 'allow' to be as close to 'auto' as possible, that would be goodness. Would it be enough to say that

        "'allow' has same meaning as 'auto' but takes priority over 'avoid'"

?

-----Original Message-----
From: www-style-request@w3.org [mailto:www-style-request@w3.org] On Behalf Of fantasai
Sent: Saturday, September 29, 2007 6:33 AM
To: Grant, Melinda
Cc: Michael Day; Håkon Wium Lie; www-style@w3.org
Subject: [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 Monday, 24 December 2007 18:44:32 UTC