Forum How do I...?

Flex grow and page spanning

markwr69
Is there a way to get flex-grow to fill the entire height of a div between pages?
Justify-content also doesn't appear to work. Align-items does, however.

.right-column {
display: flex;
flex-direction: column;
justify-content: space-between;
flex-grow: 1;
align-items: flex-end;
}

This CSS works great in the browser, with the intended result. Prince mostly ignores the CSS.
markbrown
Note that 'flex-grow' needs to be set on the items within the container, not the container itself.

Which version of Prince are you using? Could you post some input that demonstrates the problem (or send it to mikeday@yeslogic.com)?

Thanks,
Mark
markwr69
Okay, here is the code that displays the issue.

When the first column breaks to the next page, the second column does not follow and match its height. If the first column stays on one page, then the second column stretches to the correct height as expected.

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Flex test</title>
<link rel="stylesheet" type="text/css" />
<style>
.box {
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
align-items: stretch;
overflow: hidden;
}

.column1 {
width: 50%;
border: 1px solid green;
width: 500px;
}
.column2 {
width: 50%;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
flex-direction: column;
align-items: flex-end;
justify-content: space-between;
border: 1px solid blue;
width: 300px;
}

.item1 {
border: 1px solid black;
width: 200px;
margin: 2em 0;
}

.item2 {
border: 1px solid red;
width: 200px;
}

</style>
</head>
<body>

<div class="box">
<div class="column1">
<div class="item1">Item</div>
<div class="item1">Item</div>
<div class="item1">Item</div>
<div class="item1">Item</div>
<div class="item1">Item</div>
<div class="item1">Item</div>
<div class="item1">Item</div>
<div class="item1">Item</div>
<div class="item1">Item</div>
<div class="item1">Item</div>
<div class="item1">Item</div>
<div class="item1">Item</div>
<div class="item1">Item</div>
<div class="item1">Item</div>
<div class="item1">Item</div>
<div class="item1">Item</div>
<div class="item1">Item</div>
<div class="item1">Item</div>
<div class="item1">Item</div>
<div class="item1">Item</div>
</div>
<div class="column2">
<div class="item2">Item</div>
<div class="item2">Item</div>
<div class="item2">Item</div>
<div class="item2">Item</div>
<div class="item2">Item</div>
<div class="item2">Item</div>
<div class="item2">Item</div>
</div>
</div>

</body>
</html>
markbrown
Unfortunately, we only support the 'flex-start' and 'baseline' values of align-items on auto-height row containers that are fragmented across pages, so we can't handle this example right now.

If you can set a fixed height for the outer div (possibly using the two pass method) then 'align-items:stretch' should work.

Mark
markwr69
Okay, thanks for your quick response. I will look at the two pass method and see if I can figure it out.
markwr69
Do you have any tips on how to go about this?
I tried to take a stab at it and I haven't been able to make anything work.

I have included sample files.
  1. content.html2.5 kB
    HTML
  2. content.pdf38.2 kB
    PDF
markbrown
You could try the following with the first example above:
// fixheight.js
Prince.trackBoxes = true;
Prince.addEventListener("complete", fixheight, false);

function fixheight() {
    var bs = document.getElementsByClassName("box");
    for (i = 0; i < bs.length; i++) {
        var boxes = bs[i].getPrinceBoxes();
        var h = 0;
        for (j = 0; j < boxes.length; j++) { h += boxes[j].h; }
        var str = "#" + bs[i].id + " { height: " + h + "pt; }";
        console.log(str);
    }
}


(It also requires an id attribute on the "box" element.)

After Prince has finished formatting the document the above prints a snippet of CSS to the console, which you can then use in a second run. E.g.:
$ prince --script fixheight.js file.html > temp.css
$ prince --style temp.css file.html


If you have the option of modifying the markup, an alternative to the "two pass" approach is to wrap the "box" element in another flex container, with 'flex-direction: column'. This should also fix the height of the "box" element.

(Given your second example, however, there's another issue: elements with a definite height effectively have 'page-break-inside: avoid', which means in your case the body will be separated from the header once it reaches the bottom of the page. We'll need some time to address this, sorry.)

Mark
markwr69
Thank you so much Mark. I was able to utilize the javascript, and ended up appending the div value to my existing css instead of overwriting the file. So far the results are promising.

--Mark R.