Forum Feature requests

CSS Multi-column Layout Module

ibk
I gather from previous posts that Prince does not properly support page and column breaks in multi-column format, instead relying on the page-break- algorithm.
I am producing a periodical with 2-column layout including tables, and I can never quite get the breaks to go in the right places (the amount of text before and after the tables, and the length of the tables themselves, vary from one edition to the next).

Is it on the roadmap to support the breaks as detailed in "CSS Multi-column Layout Module: W3C Candidate Recommendation 17 December 2009" http://www.w3.org/TR/css3-multicol/#column-breaks. Support of these new attributes (e.g. break-inside: auto | avoid | avoid-page | avoid-column ) would be great!

I suspect http://www.princexml.com/bb/viewtopic.php?t=1908 might refer to the problem I am seeing. I am using v6.0 rev 8, but the problem remained when I did some testing with v7.1
mikeday
Have you tried using the column-break-before/after properties? We have fixed some bugs for column breaking that will be in Prince 8.0.
ibk
Thanks for the suggestion, Mike, but the property I really need to would probably be column-break-inside: avoid (or, in the CSS recommendation, break-inside: avoid). Because there are times when I don't want the tables to start at the top of a column; I just don't want them to break across columns if it can be avoided.

The problem I am seeing is how column breaks are handled where a table is longer than 1 column. The problem appears in both 6. and 7.1
Below is a sample, which I think I have reduced to the bare necessities. (BTW, how do you attach files here? It rejected .html and .txt)

Table 1 is more than 1 column long.
Table 2 is less than 1 column, as is Table 3. Indeed, Tables 2 & 3 can fit in 1 column. Table 4 is another long one.

What I would like to have happen is Table 1 (the long one) lays out across columns 1 & 2 of a page, then Tables 2 and 3 are both in the first column of page 2. Then Table 4 running from p2/c2 to p3/c1. But I can't make that happen!

If I use table {page-break-inside: auto} the result looks a mess.
But if I put table {page-break-inside: avoid} Table 1 (mysteriously) starts in column 2. Tables 2 & 3 do what I expect, and Table 4 does too.

So what is happening with Table 1? How can I make it start in column 1?

I should point out that in the real documents, the number and length of these tables can vary markedly, so I really don't want to have a special <table class="first-in-section">


<html>
<head>

<style>
 div.subsection {
  column-count: 2; 
  page-break-inside: auto;
  column-fill: auto;
 }
 table {
  page-break-inside: avoid;
 }
 th {
  background-color: yellow;
 }
 td {
  border: 1px solid red;
 }
</style>

</head>

<body>


 <div class="subsection">
  <h3>Tables subsection</h3>
  
  <table>
   <thead>
     <tr><th>Table 1: more than 1 column long</th></tr>
   </thead>
   <tbody>
    <tr><td>Row 1</td></tr>
    <tr><td>Row 2</td></tr>
    <tr><td>Row 3</td></tr>
    <tr><td>Row 4</td></tr>
    <tr><td>Row 5</td></tr>
    <tr><td>Row 6</td></tr>
    <tr><td>Row 7</td></tr>
    <tr><td>Row 8</td></tr>
    <tr><td>Row 9</td></tr>
    <tr><td>Row 10</td></tr>
    <tr><td>Row 11</td></tr>
    <tr><td>Row 12</td></tr>
    <tr><td>Row 13</td></tr>
    <tr><td>Row 14</td></tr>
    <tr><td>Row 15</td></tr>
    <tr><td>Row 16</td></tr>
    <tr><td>Row 17</td></tr>
    <tr><td>Row 18</td></tr>
    <tr><td>Row 19</td></tr>
    <tr><td>Row 20</td></tr>
    <tr><td>Row 21</td></tr>
    <tr><td>Row 22</td></tr>
    <tr><td>Row 23</td></tr>
    <tr><td>Row 24</td></tr>
    <tr><td>Row 25</td></tr>
    <tr><td>Row 26</td></tr>
    <tr><td>Row 27</td></tr>
    <tr><td>Row 28</td></tr>
    <tr><td>Row 29</td></tr>
    <tr><td>Row 30</td></tr>
    <tr><td>Row 31</td></tr>
    <tr><td>Row 32</td></tr>
    <tr><td>Row 33</td></tr>
    <tr><td>Row 34</td></tr>
    <tr><td>Row 35</td></tr>
    <tr><td>Row 36</td></tr>
    <tr><td>Row 37</td></tr>
    <tr><td>Row 38</td></tr>
    <tr><td>Row 39</td></tr>
    <tr><td>Row 40</td></tr>
    <tr><td>Row 41</td></tr>
    <tr><td>Row 42</td></tr>
    <tr><td>Row 43</td></tr>
    <tr><td>Row 44</td></tr>
    <tr><td>Row 45</td></tr>
    <tr><td>Row 46</td></tr>
    <tr><td>Row 47</td></tr>
    <tr><td>Row 48</td></tr>
    <tr><td>Row 49</td></tr>
    <tr><td>Row 50</td></tr>
    <tr><td>Row 51</td></tr>
    <tr><td>Row 52</td></tr>
    <tr><td>Row 53</td></tr>
    <tr><td>Row 54</td></tr>
    <tr><td>Row 55</td></tr>
    <tr><td>Row 56</td></tr>
    <tr><td>Row 57</td></tr>
    <tr><td>Row 58</td></tr>
    <tr><td>Row 59</td></tr>
    <tr><td>Row 60</td></tr>
   </tbody>
  </table>

  <table>
   <thead>
     <tr><th>Table 2: shorter</th></tr>
   </thead>
   <tbody>
    <tr><td>Row 1</td></tr>
    <tr><td>Row 2</td></tr>
    <tr><td>Row 3</td></tr>
    <tr><td>Row 4</td></tr>
    <tr><td>Row 5</td></tr>
    <tr><td>Row 6</td></tr>
    <tr><td>Row 7</td></tr>
    <tr><td>Row 8</td></tr>
    <tr><td>Row 9</td></tr>
    <tr><td>Row 10</td></tr>
    <tr><td>Row 11</td></tr>
    <tr><td>Row 12</td></tr>
    <tr><td>Row 13</td></tr>
    <tr><td>Row 14</td></tr>
    <tr><td>Row 15</td></tr>
    <tr><td>Row 16</td></tr>
    <tr><td>Row 17</td></tr>
    <tr><td>Row 18</td></tr>
    <tr><td>Row 19</td></tr>
    <tr><td>Row 20</td></tr>
   </tbody>
  </table>

  <table>
   <thead>
     <tr><th>Table 3: even shorter</th></tr>
   </thead>
   <tbody>
    <tr><td>Row 1</td></tr>
    <tr><td>Row 2</td></tr>
    <tr><td>Row 3</td></tr>
    <tr><td>Row 4</td></tr>
    <tr><td>Row 5</td></tr>
    <tr><td>Row 6</td></tr>
   </tbody>
  </table>
  
  <table>
   <thead>
     <tr><th>Table 4 more than 1 column long</th></tr>
   </thead>
   <tbody>
    <tr><td>Row 1</td></tr>
    <tr><td>Row 2</td></tr>
    <tr><td>Row 3</td></tr>
    <tr><td>Row 4</td></tr>
    <tr><td>Row 5</td></tr>
    <tr><td>Row 6</td></tr>
    <tr><td>Row 7</td></tr>
    <tr><td>Row 8</td></tr>
    <tr><td>Row 9</td></tr>
    <tr><td>Row 10</td></tr>
    <tr><td>Row 11</td></tr>
    <tr><td>Row 12</td></tr>
    <tr><td>Row 13</td></tr>
    <tr><td>Row 14</td></tr>
    <tr><td>Row 15</td></tr>
    <tr><td>Row 16</td></tr>
    <tr><td>Row 17</td></tr>
    <tr><td>Row 18</td></tr>
    <tr><td>Row 19</td></tr>
    <tr><td>Row 20</td></tr>
    <tr><td>Row 21</td></tr>
    <tr><td>Row 22</td></tr>
    <tr><td>Row 23</td></tr>
    <tr><td>Row 24</td></tr>
    <tr><td>Row 25</td></tr>
    <tr><td>Row 26</td></tr>
    <tr><td>Row 27</td></tr>
    <tr><td>Row 28</td></tr>
    <tr><td>Row 29</td></tr>
    <tr><td>Row 30</td></tr>
    <tr><td>Row 31</td></tr>
    <tr><td>Row 32</td></tr>
    <tr><td>Row 33</td></tr>
    <tr><td>Row 34</td></tr>
    <tr><td>Row 35</td></tr>
    <tr><td>Row 36</td></tr>
    <tr><td>Row 37</td></tr>
    <tr><td>Row 38</td></tr>
    <tr><td>Row 39</td></tr>
    <tr><td>Row 40</td></tr>
    <tr><td>Row 41</td></tr>
    <tr><td>Row 42</td></tr>
    <tr><td>Row 43</td></tr>
    <tr><td>Row 44</td></tr>
    <tr><td>Row 45</td></tr>
    <tr><td>Row 46</td></tr>
    <tr><td>Row 47</td></tr>
    <tr><td>Row 48</td></tr>
    <tr><td>Row 49</td></tr>
    <tr><td>Row 50</td></tr>
    <tr><td>Row 51</td></tr>
    <tr><td>Row 52</td></tr>
    <tr><td>Row 53</td></tr>
    <tr><td>Row 54</td></tr>
    <tr><td>Row 55</td></tr>
    <tr><td>Row 56</td></tr>
    <tr><td>Row 57</td></tr>
    <tr><td>Row 58</td></tr>
    <tr><td>Row 59</td></tr>
    <tr><td>Row 60</td></tr>
   </tbody>
  </table>
  </div>

 
 </body>
 </html>
mikeday
At the moment "page-break-inside: avoid" will also avoid column breaks, in the absence of any column-break-inside property. The issue with table 1 looks like a bug, where Prince is trying to avoid breaking it, and as a result moves it to the second column, where it gets broken anyway. We will investigate this issue.
mikeday
On closer examination, this is expected behaviour rather than a bug. Because the first column already has something in it (the "Tables subsection" heading) and Prince does not want to break the following long table, it will move the table to the start of a new column. Unfortunately, the table is long enough that it still breaks there also. To reduce the chance of this, it would be best not to use page-break-inside: avoid on very long tables, that are likely to be longer than a page anyway.
ibk
After pondering about this some more, I think I will need to use something like <table class="first-in-section">.
But I can get around it using a sibling selector, as the first-in-section table is straight after the <h3> heading:
table {  page-break-inside: avoid;}
h3 + table {  page-break-inside: auto;}

In the real-life version (as opposed to the cut-down sample), I'll have to add another <div> to hold some things together, but that's acceptable.

This at least provides a pure CSS solution: I think anything else would require knowing whether the table is "long" or "short" (that is, more or less than 1 column long). I don't think there are any CSS selectors that would let me determine that, so I'd have to process the HTML first.

Thanks for your help on this one, Mike.
mikeday
You may also be able to use "table:first-of-type" as a selector, to match the first table element in the current div for example. With the new JavaScript support in Prince 8.0 (now available in beta) it is possible to apply classes to tables based on the number of rows they contain, if that ever becomes a requirement.
bookdev
So, Mike, could you be so kind as to let me know if we could use Javascript to add a "displaynone" class to all tables whose width is greater than the Prince column width (e.g. 2in) in a multi-column layout to avoid overflows?
mikeday
Not yet, as at the moment JavaScript runs before typesetting and can't tell the ultimate width of the tables. In a future release this will be possible. :)